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.DisplayManagerGlobal;
47 import android.net.IConnectivityManager;
48 import android.net.Proxy;
49 import android.net.ProxyProperties;
50 import android.opengl.GLUtils;
51 import android.os.AsyncTask;
52 import android.os.Binder;
53 import android.os.Bundle;
54 import android.os.Debug;
55 import android.os.DropBoxManager;
56 import android.os.Environment;
57 import android.os.Handler;
58 import android.os.IBinder;
59 import android.os.Looper;
60 import android.os.Message;
61 import android.os.MessageQueue;
62 import android.os.ParcelFileDescriptor;
63 import android.os.Process;
64 import android.os.RemoteException;
65 import android.os.ServiceManager;
66 import android.os.StrictMode;
67 import android.os.SystemClock;
68 import android.os.SystemProperties;
69 import android.os.Trace;
70 import android.os.UserHandle;
71 import android.util.AndroidRuntimeException;
72 import android.util.ArrayMap;
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.util.SuperNotCalledException;
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;
90 import android.security.AndroidKeyStoreProvider;
92 import com.android.internal.os.BinderInternal;
93 import com.android.internal.os.RuntimeInit;
94 import com.android.internal.os.SamplingProfilerIntegration;
95 import com.android.internal.util.FastPrintWriter;
96 import com.android.org.conscrypt.OpenSSLSocketImpl;
97 import com.google.android.collect.Lists;
99 import dalvik.system.VMRuntime;
102 import java.io.FileDescriptor;
103 import java.io.FileOutputStream;
104 import java.io.IOException;
105 import java.io.PrintWriter;
106 import java.lang.ref.WeakReference;
107 import java.net.InetAddress;
108 import java.security.Security;
109 import java.util.ArrayList;
110 import java.util.List;
111 import java.util.Locale;
112 import java.util.Map;
113 import java.util.Objects;
114 import java.util.TimeZone;
115 import java.util.regex.Pattern;
117 import libcore.io.DropBox;
118 import libcore.io.EventLogger;
119 import libcore.io.IoUtils;
121 import dalvik.system.CloseGuard;
122 import dalvik.system.VMRuntime;
124 final class RemoteServiceException extends AndroidRuntimeException {
125 public RemoteServiceException(String msg) {
131 * This manages the execution of the main thread in an
132 * application process, scheduling and executing activities,
133 * broadcasts, and other operations on it as the activity
138 public final class ActivityThread {
140 public static final String TAG = "ActivityThread";
141 private static final android.graphics.Bitmap.Config THUMBNAIL_FORMAT = Bitmap.Config.RGB_565;
142 static final boolean localLOGV = false;
143 static final boolean DEBUG_MESSAGES = false;
145 public static final boolean DEBUG_BROADCAST = false;
146 private static final boolean DEBUG_RESULTS = false;
147 private static final boolean DEBUG_BACKUP = false;
148 public static final boolean DEBUG_CONFIGURATION = false;
149 private static final boolean DEBUG_SERVICE = false;
150 private static final boolean DEBUG_MEMORY_TRIM = false;
151 private static final boolean DEBUG_PROVIDER = false;
152 private static final long MIN_TIME_BETWEEN_GCS = 5*1000;
153 private static final Pattern PATTERN_SEMICOLON = Pattern.compile(";");
154 private static final int SQLITE_MEM_RELEASED_EVENT_LOG_TAG = 75003;
155 private static final int LOG_ON_PAUSE_CALLED = 30021;
156 private static final int LOG_ON_RESUME_CALLED = 30022;
158 private ContextImpl mSystemContext;
160 static IPackageManager sPackageManager;
162 final ApplicationThread mAppThread = new ApplicationThread();
163 final Looper mLooper = Looper.myLooper();
164 final H mH = new H();
165 final ArrayMap<IBinder, ActivityClientRecord> mActivities
166 = new ArrayMap<IBinder, ActivityClientRecord>();
167 // List of new activities (via ActivityRecord.nextIdle) that should
168 // be reported when next we idle.
169 ActivityClientRecord mNewActivities = null;
170 // Number of activities that are currently visible on-screen.
171 int mNumVisibleActivities = 0;
172 final ArrayMap<IBinder, Service> mServices
173 = new ArrayMap<IBinder, Service>();
174 AppBindData mBoundApplication;
176 int mCurDefaultDisplayDpi;
177 boolean mDensityCompatMode;
178 Configuration mConfiguration;
179 Configuration mCompatConfiguration;
180 Application mInitialApplication;
181 final ArrayList<Application> mAllApplications
182 = new ArrayList<Application>();
183 // set of instantiated backup agents, keyed by package name
184 final ArrayMap<String, BackupAgent> mBackupAgents = new ArrayMap<String, BackupAgent>();
185 /** Reference to singleton {@link ActivityThread} */
186 private static ActivityThread sCurrentActivityThread;
187 Instrumentation mInstrumentation;
188 String mInstrumentationAppDir = null;
189 String mInstrumentationAppLibraryDir = null;
190 String mInstrumentationAppPackage = null;
191 String mInstrumentedAppDir = null;
192 String mInstrumentedAppLibraryDir = null;
193 boolean mSystemThread = false;
194 boolean mJitEnabled = false;
196 // These can be accessed by multiple threads; mPackages is the lock.
197 // XXX For now we keep around information about all packages we have
198 // seen, not removing entries from this map.
199 // NOTE: The activity and window managers need to call in to
200 // ActivityThread to do things like update resource configurations,
201 // which means this lock gets held while the activity and window managers
202 // holds their own lock. Thus you MUST NEVER call back into the activity manager
203 // or window manager or anything that depends on them while holding this lock.
204 final ArrayMap<String, WeakReference<LoadedApk>> mPackages
205 = new ArrayMap<String, WeakReference<LoadedApk>>();
206 final ArrayMap<String, WeakReference<LoadedApk>> mResourcePackages
207 = new ArrayMap<String, WeakReference<LoadedApk>>();
208 final ArrayList<ActivityClientRecord> mRelaunchingActivities
209 = new ArrayList<ActivityClientRecord>();
210 Configuration mPendingConfiguration = null;
212 private final ResourcesManager mResourcesManager;
214 private static final class ProviderKey {
215 final String authority;
218 public ProviderKey(String authority, int userId) {
219 this.authority = authority;
220 this.userId = userId;
224 public boolean equals(Object o) {
225 if (o instanceof ProviderKey) {
226 final ProviderKey other = (ProviderKey) o;
227 return Objects.equals(authority, other.authority) && userId == other.userId;
233 public int hashCode() {
234 return ((authority != null) ? authority.hashCode() : 0) ^ userId;
238 // The lock of mProviderMap protects the following variables.
239 final ArrayMap<ProviderKey, ProviderClientRecord> mProviderMap
240 = new ArrayMap<ProviderKey, ProviderClientRecord>();
241 final ArrayMap<IBinder, ProviderRefCount> mProviderRefCountMap
242 = new ArrayMap<IBinder, ProviderRefCount>();
243 final ArrayMap<IBinder, ProviderClientRecord> mLocalProviders
244 = new ArrayMap<IBinder, ProviderClientRecord>();
245 final ArrayMap<ComponentName, ProviderClientRecord> mLocalProvidersByName
246 = new ArrayMap<ComponentName, ProviderClientRecord>();
248 final ArrayMap<Activity, ArrayList<OnActivityPausedListener>> mOnPauseListeners
249 = new ArrayMap<Activity, ArrayList<OnActivityPausedListener>>();
251 final GcIdler mGcIdler = new GcIdler();
252 boolean mGcIdlerScheduled = false;
254 static Handler sMainThreadHandler; // set once in main()
256 Bundle mCoreSettings = null;
258 static final class ActivityClientRecord {
267 Activity.NonConfigurationInstances lastNonConfigurationInstances;
271 Configuration newConfig;
272 Configuration createdConfig;
273 ActivityClientRecord nextIdle;
276 ParcelFileDescriptor profileFd;
277 boolean autoStopProfiler;
279 ActivityInfo activityInfo;
280 CompatibilityInfo compatInfo;
281 LoadedApk packageInfo;
283 List<ResultInfo> pendingResults;
284 List<Intent> pendingIntents;
286 boolean startsNotResumed;
288 int pendingConfigChanges;
289 boolean onlyLocalRequest;
291 View mPendingRemoveWindow;
292 WindowManager mPendingRemoveWindowManager;
294 ActivityClientRecord() {
303 public boolean isPreHoneycomb() {
304 if (activity != null) {
305 return activity.getApplicationInfo().targetSdkVersion
306 < android.os.Build.VERSION_CODES.HONEYCOMB;
311 public String toString() {
312 ComponentName componentName = intent != null ? intent.getComponent() : null;
313 return "ActivityRecord{"
314 + Integer.toHexString(System.identityHashCode(this))
315 + " token=" + token + " " + (componentName == null
316 ? "no component name" : componentName.toShortString())
321 final class ProviderClientRecord {
322 final String[] mNames;
323 final IContentProvider mProvider;
324 final ContentProvider mLocalProvider;
325 final IActivityManager.ContentProviderHolder mHolder;
327 ProviderClientRecord(String[] names, IContentProvider provider,
328 ContentProvider localProvider,
329 IActivityManager.ContentProviderHolder holder) {
331 mProvider = provider;
332 mLocalProvider = localProvider;
337 static final class NewIntentData {
338 List<Intent> intents;
340 public String toString() {
341 return "NewIntentData{intents=" + intents + " token=" + token + "}";
345 static final class ReceiverData extends BroadcastReceiver.PendingResult {
346 public ReceiverData(Intent intent, int resultCode, String resultData, Bundle resultExtras,
347 boolean ordered, boolean sticky, IBinder token, int sendingUser) {
348 super(resultCode, resultData, resultExtras, TYPE_COMPONENT, ordered, sticky,
350 this.intent = intent;
355 CompatibilityInfo compatInfo;
356 public String toString() {
357 return "ReceiverData{intent=" + intent + " packageName=" +
358 info.packageName + " resultCode=" + getResultCode()
359 + " resultData=" + getResultData() + " resultExtras="
360 + getResultExtras(false) + "}";
364 static final class CreateBackupAgentData {
365 ApplicationInfo appInfo;
366 CompatibilityInfo compatInfo;
368 public String toString() {
369 return "CreateBackupAgentData{appInfo=" + appInfo
370 + " backupAgent=" + appInfo.backupAgentName
371 + " mode=" + backupMode + "}";
375 static final class CreateServiceData {
378 CompatibilityInfo compatInfo;
380 public String toString() {
381 return "CreateServiceData{token=" + token + " className="
382 + info.name + " packageName=" + info.packageName
383 + " intent=" + intent + "}";
387 static final class BindServiceData {
391 public String toString() {
392 return "BindServiceData{token=" + token + " intent=" + intent + "}";
396 static final class ServiceArgsData {
402 public String toString() {
403 return "ServiceArgsData{token=" + token + " startId=" + startId
404 + " args=" + args + "}";
408 static final class AppBindData {
411 ApplicationInfo appInfo;
412 List<ProviderInfo> providers;
413 ComponentName instrumentationName;
414 Bundle instrumentationArgs;
415 IInstrumentationWatcher instrumentationWatcher;
416 IUiAutomationConnection instrumentationUiAutomationConnection;
418 boolean enableOpenGlTrace;
419 boolean restrictedBackupMode;
421 Configuration config;
422 CompatibilityInfo compatInfo;
424 /** Initial values for {@link Profiler}. */
425 String initProfileFile;
426 ParcelFileDescriptor initProfileFd;
427 boolean initAutoStopProfiler;
429 public String toString() {
430 return "AppBindData{appInfo=" + appInfo + "}";
434 static final class Profiler {
436 ParcelFileDescriptor profileFd;
437 boolean autoStopProfiler;
439 boolean handlingProfiling;
440 public void setProfiler(String file, ParcelFileDescriptor fd) {
445 } catch (IOException e) {
451 if (profileFd != null) {
454 } catch (IOException e) {
461 public void startProfiling() {
462 if (profileFd == null || profiling) {
466 Debug.startMethodTracing(profileFile, profileFd.getFileDescriptor(),
469 } catch (RuntimeException e) {
470 Slog.w(TAG, "Profiling failed on path " + profileFile);
474 } catch (IOException e2) {
475 Slog.w(TAG, "Failure closing profile fd", e2);
479 public void stopProfiling() {
482 Debug.stopMethodTracing();
483 if (profileFd != null) {
486 } catch (IOException e) {
495 static final class DumpComponentInfo {
496 ParcelFileDescriptor fd;
502 static final class ResultData {
504 List<ResultInfo> results;
505 public String toString() {
506 return "ResultData{token=" + token + " results" + results + "}";
510 static final class ContextCleanupInfo {
516 static final class ProfilerControlData {
518 ParcelFileDescriptor fd;
521 static final class DumpHeapData {
523 ParcelFileDescriptor fd;
526 static final class UpdateCompatibilityData {
528 CompatibilityInfo info;
531 static final class RequestAssistContextExtras {
532 IBinder activityToken;
533 IBinder requestToken;
537 private native void dumpGraphicsInfo(FileDescriptor fd);
539 private class ApplicationThread extends ApplicationThreadNative {
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 private int mLastProcessState = -1;
546 private void updatePendingConfiguration(Configuration config) {
547 synchronized (mResourcesManager) {
548 if (mPendingConfiguration == null ||
549 mPendingConfiguration.isOtherSeqNewer(config)) {
550 mPendingConfiguration = config;
555 public final void schedulePauseActivity(IBinder token, boolean finished,
556 boolean userLeaving, int configChanges) {
558 finished ? H.PAUSE_ACTIVITY_FINISHING : H.PAUSE_ACTIVITY,
560 (userLeaving ? 1 : 0),
564 public final void scheduleStopActivity(IBinder token, boolean showWindow,
567 showWindow ? H.STOP_ACTIVITY_SHOW : H.STOP_ACTIVITY_HIDE,
568 token, 0, configChanges);
571 public final void scheduleWindowVisibility(IBinder token, boolean showWindow) {
573 showWindow ? H.SHOW_WINDOW : H.HIDE_WINDOW,
577 public final void scheduleSleeping(IBinder token, boolean sleeping) {
578 sendMessage(H.SLEEPING, token, sleeping ? 1 : 0);
581 public final void scheduleResumeActivity(IBinder token, int processState,
583 updateProcessState(processState, false);
584 sendMessage(H.RESUME_ACTIVITY, token, isForward ? 1 : 0);
587 public final void scheduleSendResult(IBinder token, List<ResultInfo> results) {
588 ResultData res = new ResultData();
590 res.results = results;
591 sendMessage(H.SEND_RESULT, res);
594 // we use token to identify this activity without having to send the
595 // activity itself back to the activity manager. (matters more with ipc)
596 public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
597 ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo,
598 int procState, Bundle state, List<ResultInfo> pendingResults,
599 List<Intent> pendingNewIntents, boolean notResumed, boolean isForward,
600 String profileName, ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
602 updateProcessState(procState, false);
604 ActivityClientRecord r = new ActivityClientRecord();
609 r.activityInfo = info;
610 r.compatInfo = compatInfo;
613 r.pendingResults = pendingResults;
614 r.pendingIntents = pendingNewIntents;
616 r.startsNotResumed = notResumed;
617 r.isForward = isForward;
619 r.profileFile = profileName;
620 r.profileFd = profileFd;
621 r.autoStopProfiler = autoStopProfiler;
623 updatePendingConfiguration(curConfig);
625 sendMessage(H.LAUNCH_ACTIVITY, r);
628 public final void scheduleRelaunchActivity(IBinder token,
629 List<ResultInfo> pendingResults, List<Intent> pendingNewIntents,
630 int configChanges, boolean notResumed, Configuration config) {
631 requestRelaunchActivity(token, pendingResults, pendingNewIntents,
632 configChanges, notResumed, config, true);
635 public final void scheduleNewIntent(List<Intent> intents, IBinder token) {
636 NewIntentData data = new NewIntentData();
637 data.intents = intents;
640 sendMessage(H.NEW_INTENT, data);
643 public final void scheduleDestroyActivity(IBinder token, boolean finishing,
645 sendMessage(H.DESTROY_ACTIVITY, token, finishing ? 1 : 0,
649 public final void scheduleReceiver(Intent intent, ActivityInfo info,
650 CompatibilityInfo compatInfo, int resultCode, String data, Bundle extras,
651 boolean sync, int sendingUser, int processState) {
652 updateProcessState(processState, false);
653 ReceiverData r = new ReceiverData(intent, resultCode, data, extras,
654 sync, false, mAppThread.asBinder(), sendingUser);
656 r.compatInfo = compatInfo;
657 sendMessage(H.RECEIVER, r);
660 public final void scheduleCreateBackupAgent(ApplicationInfo app,
661 CompatibilityInfo compatInfo, int backupMode) {
662 CreateBackupAgentData d = new CreateBackupAgentData();
664 d.compatInfo = compatInfo;
665 d.backupMode = backupMode;
667 sendMessage(H.CREATE_BACKUP_AGENT, d);
670 public final void scheduleDestroyBackupAgent(ApplicationInfo app,
671 CompatibilityInfo compatInfo) {
672 CreateBackupAgentData d = new CreateBackupAgentData();
674 d.compatInfo = compatInfo;
676 sendMessage(H.DESTROY_BACKUP_AGENT, d);
679 public final void scheduleCreateService(IBinder token,
680 ServiceInfo info, CompatibilityInfo compatInfo, int processState) {
681 updateProcessState(processState, false);
682 CreateServiceData s = new CreateServiceData();
685 s.compatInfo = compatInfo;
687 sendMessage(H.CREATE_SERVICE, s);
690 public final void scheduleBindService(IBinder token, Intent intent,
691 boolean rebind, int processState) {
692 updateProcessState(processState, false);
693 BindServiceData s = new BindServiceData();
699 Slog.v(TAG, "scheduleBindService token=" + token + " intent=" + intent + " uid="
700 + Binder.getCallingUid() + " pid=" + Binder.getCallingPid());
701 sendMessage(H.BIND_SERVICE, s);
704 public final void scheduleUnbindService(IBinder token, Intent intent) {
705 BindServiceData s = new BindServiceData();
709 sendMessage(H.UNBIND_SERVICE, s);
712 public final void scheduleServiceArgs(IBinder token, boolean taskRemoved, int startId,
713 int flags ,Intent args) {
714 ServiceArgsData s = new ServiceArgsData();
716 s.taskRemoved = taskRemoved;
721 sendMessage(H.SERVICE_ARGS, s);
724 public final void scheduleStopService(IBinder token) {
725 sendMessage(H.STOP_SERVICE, token);
728 public final void bindApplication(String processName,
729 ApplicationInfo appInfo, List<ProviderInfo> providers,
730 ComponentName instrumentationName, String profileFile,
731 ParcelFileDescriptor profileFd, boolean autoStopProfiler,
732 Bundle instrumentationArgs, IInstrumentationWatcher instrumentationWatcher,
733 IUiAutomationConnection instrumentationUiConnection, int debugMode,
734 boolean enableOpenGlTrace, boolean isRestrictedBackupMode, boolean persistent,
735 Configuration config, CompatibilityInfo compatInfo, Map<String, IBinder> services,
736 Bundle coreSettings) {
738 if (services != null) {
739 // Setup the service cache in the ServiceManager
740 ServiceManager.initServiceCache(services);
743 setCoreSettings(coreSettings);
745 // Tell the VMRuntime about the application.
746 VMRuntime.registerAppInfo(appInfo.dataDir, appInfo.processName);
748 AppBindData data = new AppBindData();
749 data.processName = processName;
750 data.appInfo = appInfo;
751 data.providers = providers;
752 data.instrumentationName = instrumentationName;
753 data.instrumentationArgs = instrumentationArgs;
754 data.instrumentationWatcher = instrumentationWatcher;
755 data.instrumentationUiAutomationConnection = instrumentationUiConnection;
756 data.debugMode = debugMode;
757 data.enableOpenGlTrace = enableOpenGlTrace;
758 data.restrictedBackupMode = isRestrictedBackupMode;
759 data.persistent = persistent;
760 data.config = config;
761 data.compatInfo = compatInfo;
762 data.initProfileFile = profileFile;
763 data.initProfileFd = profileFd;
764 data.initAutoStopProfiler = false;
765 sendMessage(H.BIND_APPLICATION, data);
768 public final void scheduleExit() {
769 sendMessage(H.EXIT_APPLICATION, null);
772 public final void scheduleSuicide() {
773 sendMessage(H.SUICIDE, null);
776 public void requestThumbnail(IBinder token) {
777 sendMessage(H.REQUEST_THUMBNAIL, token);
780 public void scheduleConfigurationChanged(Configuration config) {
781 updatePendingConfiguration(config);
782 sendMessage(H.CONFIGURATION_CHANGED, config);
785 public void updateTimeZone() {
786 TimeZone.setDefault(null);
789 public void clearDnsCache() {
790 // a non-standard API to get this to libcore
791 InetAddress.clearDnsCache();
794 public void setHttpProxy(String host, String port, String exclList, String pacFileUrl) {
795 Proxy.setHttpProxySystemProperty(host, port, exclList, pacFileUrl);
798 public void processInBackground() {
799 mH.removeMessages(H.GC_WHEN_IDLE);
800 mH.sendMessage(mH.obtainMessage(H.GC_WHEN_IDLE));
803 public void dumpService(FileDescriptor fd, IBinder servicetoken, String[] args) {
804 DumpComponentInfo data = new DumpComponentInfo();
806 data.fd = ParcelFileDescriptor.dup(fd);
807 data.token = servicetoken;
809 sendMessage(H.DUMP_SERVICE, data, 0, 0, true /*async*/);
810 } catch (IOException e) {
811 Slog.w(TAG, "dumpService failed", e);
815 // This function exists to make sure all receiver dispatching is
816 // correctly ordered, since these are one-way calls and the binder driver
817 // applies transaction ordering per object for such calls.
818 public void scheduleRegisteredReceiver(IIntentReceiver receiver, Intent intent,
819 int resultCode, String dataStr, Bundle extras, boolean ordered,
820 boolean sticky, int sendingUser, int processState) throws RemoteException {
821 updateProcessState(processState, false);
822 receiver.performReceive(intent, resultCode, dataStr, extras, ordered,
823 sticky, sendingUser);
826 public void scheduleLowMemory() {
827 sendMessage(H.LOW_MEMORY, null);
830 public void scheduleActivityConfigurationChanged(IBinder token) {
831 sendMessage(H.ACTIVITY_CONFIGURATION_CHANGED, token);
834 public void profilerControl(boolean start, String path, ParcelFileDescriptor fd,
836 ProfilerControlData pcd = new ProfilerControlData();
839 sendMessage(H.PROFILER_CONTROL, pcd, start ? 1 : 0, profileType);
842 public void dumpHeap(boolean managed, String path, ParcelFileDescriptor fd) {
843 DumpHeapData dhd = new DumpHeapData();
846 sendMessage(H.DUMP_HEAP, dhd, managed ? 1 : 0, 0, true /*async*/);
849 public void setSchedulingGroup(int group) {
850 // Note: do this immediately, since going into the foreground
851 // should happen regardless of what pending work we have to do
852 // and the activity manager will wait for us to report back that
853 // we are done before sending us to the background.
855 Process.setProcessGroup(Process.myPid(), group);
856 } catch (Exception e) {
857 Slog.w(TAG, "Failed setting process group to " + group, e);
861 public void dispatchPackageBroadcast(int cmd, String[] packages) {
862 sendMessage(H.DISPATCH_PACKAGE_BROADCAST, packages, cmd);
865 public void scheduleCrash(String msg) {
866 sendMessage(H.SCHEDULE_CRASH, msg);
869 public void dumpActivity(FileDescriptor fd, IBinder activitytoken,
870 String prefix, String[] args) {
871 DumpComponentInfo data = new DumpComponentInfo();
873 data.fd = ParcelFileDescriptor.dup(fd);
874 data.token = activitytoken;
875 data.prefix = prefix;
877 sendMessage(H.DUMP_ACTIVITY, data, 0, 0, true /*async*/);
878 } catch (IOException e) {
879 Slog.w(TAG, "dumpActivity failed", e);
883 public void dumpProvider(FileDescriptor fd, IBinder providertoken,
885 DumpComponentInfo data = new DumpComponentInfo();
887 data.fd = ParcelFileDescriptor.dup(fd);
888 data.token = providertoken;
890 sendMessage(H.DUMP_PROVIDER, data, 0, 0, true /*async*/);
891 } catch (IOException e) {
892 Slog.w(TAG, "dumpProvider failed", e);
897 public void dumpMemInfo(FileDescriptor fd, Debug.MemoryInfo mem, boolean checkin,
898 boolean dumpFullInfo, boolean dumpDalvik, String[] args) {
899 FileOutputStream fout = new FileOutputStream(fd);
900 PrintWriter pw = new FastPrintWriter(fout);
902 dumpMemInfo(pw, mem, checkin, dumpFullInfo, dumpDalvik);
908 private void dumpMemInfo(PrintWriter pw, Debug.MemoryInfo memInfo, boolean checkin,
909 boolean dumpFullInfo, boolean dumpDalvik) {
910 long nativeMax = Debug.getNativeHeapSize() / 1024;
911 long nativeAllocated = Debug.getNativeHeapAllocatedSize() / 1024;
912 long nativeFree = Debug.getNativeHeapFreeSize() / 1024;
914 Runtime runtime = Runtime.getRuntime();
916 long dalvikMax = runtime.totalMemory() / 1024;
917 long dalvikFree = runtime.freeMemory() / 1024;
918 long dalvikAllocated = dalvikMax - dalvikFree;
919 long viewInstanceCount = ViewDebug.getViewInstanceCount();
920 long viewRootInstanceCount = ViewDebug.getViewRootImplCount();
921 long appContextInstanceCount = Debug.countInstancesOfClass(ContextImpl.class);
922 long activityInstanceCount = Debug.countInstancesOfClass(Activity.class);
923 int globalAssetCount = AssetManager.getGlobalAssetCount();
924 int globalAssetManagerCount = AssetManager.getGlobalAssetManagerCount();
925 int binderLocalObjectCount = Debug.getBinderLocalObjectCount();
926 int binderProxyObjectCount = Debug.getBinderProxyObjectCount();
927 int binderDeathObjectCount = Debug.getBinderDeathObjectCount();
928 long openSslSocketCount = Debug.countInstancesOfClass(OpenSSLSocketImpl.class);
929 SQLiteDebug.PagerStats stats = SQLiteDebug.getDatabaseInfo();
931 dumpMemInfoTable(pw, memInfo, checkin, dumpFullInfo, dumpDalvik, Process.myPid(),
932 (mBoundApplication != null) ? mBoundApplication.processName : "unknown",
933 nativeMax, nativeAllocated, nativeFree,
934 dalvikMax, dalvikAllocated, dalvikFree);
937 // NOTE: if you change anything significant below, also consider changing
938 // ACTIVITY_THREAD_CHECKIN_VERSION.
941 pw.print(viewInstanceCount); pw.print(',');
942 pw.print(viewRootInstanceCount); pw.print(',');
943 pw.print(appContextInstanceCount); pw.print(',');
944 pw.print(activityInstanceCount); pw.print(',');
946 pw.print(globalAssetCount); pw.print(',');
947 pw.print(globalAssetManagerCount); pw.print(',');
948 pw.print(binderLocalObjectCount); pw.print(',');
949 pw.print(binderProxyObjectCount); pw.print(',');
951 pw.print(binderDeathObjectCount); pw.print(',');
952 pw.print(openSslSocketCount); pw.print(',');
955 pw.print(stats.memoryUsed / 1024); pw.print(',');
956 pw.print(stats.memoryUsed / 1024); pw.print(',');
957 pw.print(stats.pageCacheOverflow / 1024); pw.print(',');
958 pw.print(stats.largestMemAlloc / 1024);
959 for (int i = 0; i < stats.dbStats.size(); i++) {
960 DbStats dbStats = stats.dbStats.get(i);
961 pw.print(','); pw.print(dbStats.dbName);
962 pw.print(','); pw.print(dbStats.pageSize);
963 pw.print(','); pw.print(dbStats.dbSize);
964 pw.print(','); pw.print(dbStats.lookaside);
965 pw.print(','); pw.print(dbStats.cache);
966 pw.print(','); pw.print(dbStats.cache);
974 pw.println(" Objects");
975 printRow(pw, TWO_COUNT_COLUMNS, "Views:", viewInstanceCount, "ViewRootImpl:",
976 viewRootInstanceCount);
978 printRow(pw, TWO_COUNT_COLUMNS, "AppContexts:", appContextInstanceCount,
979 "Activities:", activityInstanceCount);
981 printRow(pw, TWO_COUNT_COLUMNS, "Assets:", globalAssetCount,
982 "AssetManagers:", globalAssetManagerCount);
984 printRow(pw, TWO_COUNT_COLUMNS, "Local Binders:", binderLocalObjectCount,
985 "Proxy Binders:", binderProxyObjectCount);
986 printRow(pw, ONE_COUNT_COLUMN, "Death Recipients:", binderDeathObjectCount);
988 printRow(pw, ONE_COUNT_COLUMN, "OpenSSL Sockets:", openSslSocketCount);
993 printRow(pw, ONE_COUNT_COLUMN, "MEMORY_USED:", stats.memoryUsed / 1024);
994 printRow(pw, TWO_COUNT_COLUMNS, "PAGECACHE_OVERFLOW:",
995 stats.pageCacheOverflow / 1024, "MALLOC_SIZE:", stats.largestMemAlloc / 1024);
997 int N = stats.dbStats.size();
999 pw.println(" DATABASES");
1000 printRow(pw, " %8s %8s %14s %14s %s", "pgsz", "dbsz", "Lookaside(b)", "cache",
1002 for (int i = 0; i < N; i++) {
1003 DbStats dbStats = stats.dbStats.get(i);
1004 printRow(pw, DB_INFO_FORMAT,
1005 (dbStats.pageSize > 0) ? String.valueOf(dbStats.pageSize) : " ",
1006 (dbStats.dbSize > 0) ? String.valueOf(dbStats.dbSize) : " ",
1007 (dbStats.lookaside > 0) ? String.valueOf(dbStats.lookaside) : " ",
1008 dbStats.cache, dbStats.dbName);
1013 String assetAlloc = AssetManager.getAssetAllocations();
1014 if (assetAlloc != null) {
1016 pw.println(" Asset Allocations");
1017 pw.print(assetAlloc);
1022 public void dumpGfxInfo(FileDescriptor fd, String[] args) {
1023 dumpGraphicsInfo(fd);
1024 WindowManagerGlobal.getInstance().dumpGfxInfo(fd);
1028 public void dumpDbInfo(FileDescriptor fd, String[] args) {
1029 PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd));
1030 PrintWriterPrinter printer = new PrintWriterPrinter(pw);
1031 SQLiteDebug.dump(printer, args);
1036 public void unstableProviderDied(IBinder provider) {
1037 sendMessage(H.UNSTABLE_PROVIDER_DIED, provider);
1041 public void requestAssistContextExtras(IBinder activityToken, IBinder requestToken,
1043 RequestAssistContextExtras cmd = new RequestAssistContextExtras();
1044 cmd.activityToken = activityToken;
1045 cmd.requestToken = requestToken;
1046 cmd.requestType = requestType;
1047 sendMessage(H.REQUEST_ASSIST_CONTEXT_EXTRAS, cmd);
1050 public void setCoreSettings(Bundle coreSettings) {
1051 sendMessage(H.SET_CORE_SETTINGS, coreSettings);
1054 public void updatePackageCompatibilityInfo(String pkg, CompatibilityInfo info) {
1055 UpdateCompatibilityData ucd = new UpdateCompatibilityData();
1058 sendMessage(H.UPDATE_PACKAGE_COMPATIBILITY_INFO, ucd);
1061 public void scheduleTrimMemory(int level) {
1062 sendMessage(H.TRIM_MEMORY, null, level);
1065 public void scheduleTranslucentConversionComplete(IBinder token, boolean drawComplete) {
1066 sendMessage(H.TRANSLUCENT_CONVERSION_COMPLETE, token, drawComplete ? 1 : 0);
1069 public void setProcessState(int state) {
1070 updateProcessState(state, true);
1073 public void updateProcessState(int processState, boolean fromIpc) {
1074 synchronized (this) {
1075 if (mLastProcessState != processState) {
1076 mLastProcessState = processState;
1077 // Update Dalvik state based on ActivityManager.PROCESS_STATE_* constants.
1078 final int DALVIK_PROCESS_STATE_JANK_PERCEPTIBLE = 0;
1079 final int DALVIK_PROCESS_STATE_JANK_IMPERCEPTIBLE = 1;
1080 int dalvikProcessState = DALVIK_PROCESS_STATE_JANK_IMPERCEPTIBLE;
1081 // TODO: Tune this since things like gmail sync are important background but not jank perceptible.
1082 if (processState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
1083 dalvikProcessState = DALVIK_PROCESS_STATE_JANK_PERCEPTIBLE;
1085 VMRuntime.getRuntime().updateProcessState(dalvikProcessState);
1087 Slog.i(TAG, "******************* PROCESS STATE CHANGED TO: " + processState
1088 + (fromIpc ? " (from ipc": ""));
1095 public void scheduleInstallProvider(ProviderInfo provider) {
1096 sendMessage(H.INSTALL_PROVIDER, provider);
1100 private class H extends Handler {
1101 public static final int LAUNCH_ACTIVITY = 100;
1102 public static final int PAUSE_ACTIVITY = 101;
1103 public static final int PAUSE_ACTIVITY_FINISHING= 102;
1104 public static final int STOP_ACTIVITY_SHOW = 103;
1105 public static final int STOP_ACTIVITY_HIDE = 104;
1106 public static final int SHOW_WINDOW = 105;
1107 public static final int HIDE_WINDOW = 106;
1108 public static final int RESUME_ACTIVITY = 107;
1109 public static final int SEND_RESULT = 108;
1110 public static final int DESTROY_ACTIVITY = 109;
1111 public static final int BIND_APPLICATION = 110;
1112 public static final int EXIT_APPLICATION = 111;
1113 public static final int NEW_INTENT = 112;
1114 public static final int RECEIVER = 113;
1115 public static final int CREATE_SERVICE = 114;
1116 public static final int SERVICE_ARGS = 115;
1117 public static final int STOP_SERVICE = 116;
1118 public static final int REQUEST_THUMBNAIL = 117;
1119 public static final int CONFIGURATION_CHANGED = 118;
1120 public static final int CLEAN_UP_CONTEXT = 119;
1121 public static final int GC_WHEN_IDLE = 120;
1122 public static final int BIND_SERVICE = 121;
1123 public static final int UNBIND_SERVICE = 122;
1124 public static final int DUMP_SERVICE = 123;
1125 public static final int LOW_MEMORY = 124;
1126 public static final int ACTIVITY_CONFIGURATION_CHANGED = 125;
1127 public static final int RELAUNCH_ACTIVITY = 126;
1128 public static final int PROFILER_CONTROL = 127;
1129 public static final int CREATE_BACKUP_AGENT = 128;
1130 public static final int DESTROY_BACKUP_AGENT = 129;
1131 public static final int SUICIDE = 130;
1132 public static final int REMOVE_PROVIDER = 131;
1133 public static final int ENABLE_JIT = 132;
1134 public static final int DISPATCH_PACKAGE_BROADCAST = 133;
1135 public static final int SCHEDULE_CRASH = 134;
1136 public static final int DUMP_HEAP = 135;
1137 public static final int DUMP_ACTIVITY = 136;
1138 public static final int SLEEPING = 137;
1139 public static final int SET_CORE_SETTINGS = 138;
1140 public static final int UPDATE_PACKAGE_COMPATIBILITY_INFO = 139;
1141 public static final int TRIM_MEMORY = 140;
1142 public static final int DUMP_PROVIDER = 141;
1143 public static final int UNSTABLE_PROVIDER_DIED = 142;
1144 public static final int REQUEST_ASSIST_CONTEXT_EXTRAS = 143;
1145 public static final int TRANSLUCENT_CONVERSION_COMPLETE = 144;
1146 public static final int INSTALL_PROVIDER = 145;
1147 String codeToString(int code) {
1148 if (DEBUG_MESSAGES) {
1150 case LAUNCH_ACTIVITY: return "LAUNCH_ACTIVITY";
1151 case PAUSE_ACTIVITY: return "PAUSE_ACTIVITY";
1152 case PAUSE_ACTIVITY_FINISHING: return "PAUSE_ACTIVITY_FINISHING";
1153 case STOP_ACTIVITY_SHOW: return "STOP_ACTIVITY_SHOW";
1154 case STOP_ACTIVITY_HIDE: return "STOP_ACTIVITY_HIDE";
1155 case SHOW_WINDOW: return "SHOW_WINDOW";
1156 case HIDE_WINDOW: return "HIDE_WINDOW";
1157 case RESUME_ACTIVITY: return "RESUME_ACTIVITY";
1158 case SEND_RESULT: return "SEND_RESULT";
1159 case DESTROY_ACTIVITY: return "DESTROY_ACTIVITY";
1160 case BIND_APPLICATION: return "BIND_APPLICATION";
1161 case EXIT_APPLICATION: return "EXIT_APPLICATION";
1162 case NEW_INTENT: return "NEW_INTENT";
1163 case RECEIVER: return "RECEIVER";
1164 case CREATE_SERVICE: return "CREATE_SERVICE";
1165 case SERVICE_ARGS: return "SERVICE_ARGS";
1166 case STOP_SERVICE: return "STOP_SERVICE";
1167 case REQUEST_THUMBNAIL: return "REQUEST_THUMBNAIL";
1168 case CONFIGURATION_CHANGED: return "CONFIGURATION_CHANGED";
1169 case CLEAN_UP_CONTEXT: return "CLEAN_UP_CONTEXT";
1170 case GC_WHEN_IDLE: return "GC_WHEN_IDLE";
1171 case BIND_SERVICE: return "BIND_SERVICE";
1172 case UNBIND_SERVICE: return "UNBIND_SERVICE";
1173 case DUMP_SERVICE: return "DUMP_SERVICE";
1174 case LOW_MEMORY: return "LOW_MEMORY";
1175 case ACTIVITY_CONFIGURATION_CHANGED: return "ACTIVITY_CONFIGURATION_CHANGED";
1176 case RELAUNCH_ACTIVITY: return "RELAUNCH_ACTIVITY";
1177 case PROFILER_CONTROL: return "PROFILER_CONTROL";
1178 case CREATE_BACKUP_AGENT: return "CREATE_BACKUP_AGENT";
1179 case DESTROY_BACKUP_AGENT: return "DESTROY_BACKUP_AGENT";
1180 case SUICIDE: return "SUICIDE";
1181 case REMOVE_PROVIDER: return "REMOVE_PROVIDER";
1182 case ENABLE_JIT: return "ENABLE_JIT";
1183 case DISPATCH_PACKAGE_BROADCAST: return "DISPATCH_PACKAGE_BROADCAST";
1184 case SCHEDULE_CRASH: return "SCHEDULE_CRASH";
1185 case DUMP_HEAP: return "DUMP_HEAP";
1186 case DUMP_ACTIVITY: return "DUMP_ACTIVITY";
1187 case SLEEPING: return "SLEEPING";
1188 case SET_CORE_SETTINGS: return "SET_CORE_SETTINGS";
1189 case UPDATE_PACKAGE_COMPATIBILITY_INFO: return "UPDATE_PACKAGE_COMPATIBILITY_INFO";
1190 case TRIM_MEMORY: return "TRIM_MEMORY";
1191 case DUMP_PROVIDER: return "DUMP_PROVIDER";
1192 case UNSTABLE_PROVIDER_DIED: return "UNSTABLE_PROVIDER_DIED";
1193 case REQUEST_ASSIST_CONTEXT_EXTRAS: return "REQUEST_ASSIST_CONTEXT_EXTRAS";
1194 case TRANSLUCENT_CONVERSION_COMPLETE: return "TRANSLUCENT_CONVERSION_COMPLETE";
1195 case INSTALL_PROVIDER: return "INSTALL_PROVIDER";
1198 return Integer.toString(code);
1200 public void handleMessage(Message msg) {
1201 if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
1203 case LAUNCH_ACTIVITY: {
1204 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
1205 ActivityClientRecord r = (ActivityClientRecord)msg.obj;
1207 r.packageInfo = getPackageInfoNoCheck(
1208 r.activityInfo.applicationInfo, r.compatInfo);
1209 handleLaunchActivity(r, null);
1210 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1212 case RELAUNCH_ACTIVITY: {
1213 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityRestart");
1214 ActivityClientRecord r = (ActivityClientRecord)msg.obj;
1215 handleRelaunchActivity(r);
1216 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1218 case PAUSE_ACTIVITY:
1219 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
1220 handlePauseActivity((IBinder)msg.obj, false, msg.arg1 != 0, msg.arg2);
1222 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1224 case PAUSE_ACTIVITY_FINISHING:
1225 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
1226 handlePauseActivity((IBinder)msg.obj, true, msg.arg1 != 0, msg.arg2);
1227 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1229 case STOP_ACTIVITY_SHOW:
1230 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStop");
1231 handleStopActivity((IBinder)msg.obj, true, msg.arg2);
1232 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1234 case STOP_ACTIVITY_HIDE:
1235 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStop");
1236 handleStopActivity((IBinder)msg.obj, false, msg.arg2);
1237 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1240 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityShowWindow");
1241 handleWindowVisibility((IBinder)msg.obj, true);
1242 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1245 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityHideWindow");
1246 handleWindowVisibility((IBinder)msg.obj, false);
1247 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1249 case RESUME_ACTIVITY:
1250 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityResume");
1251 handleResumeActivity((IBinder)msg.obj, true,
1252 msg.arg1 != 0, true);
1253 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1256 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityDeliverResult");
1257 handleSendResult((ResultData)msg.obj);
1258 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1260 case DESTROY_ACTIVITY:
1261 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityDestroy");
1262 handleDestroyActivity((IBinder)msg.obj, msg.arg1 != 0,
1264 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1266 case BIND_APPLICATION:
1267 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
1268 AppBindData data = (AppBindData)msg.obj;
1269 handleBindApplication(data);
1270 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1272 case EXIT_APPLICATION:
1273 if (mInitialApplication != null) {
1274 mInitialApplication.onTerminate();
1276 Looper.myLooper().quit();
1279 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityNewIntent");
1280 handleNewIntent((NewIntentData)msg.obj);
1281 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1284 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "broadcastReceiveComp");
1285 handleReceiver((ReceiverData)msg.obj);
1287 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1289 case CREATE_SERVICE:
1290 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceCreate");
1291 handleCreateService((CreateServiceData)msg.obj);
1292 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1295 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceBind");
1296 handleBindService((BindServiceData)msg.obj);
1297 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1299 case UNBIND_SERVICE:
1300 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceUnbind");
1301 handleUnbindService((BindServiceData)msg.obj);
1302 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1305 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceStart");
1306 handleServiceArgs((ServiceArgsData)msg.obj);
1307 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1310 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceStop");
1311 handleStopService((IBinder)msg.obj);
1313 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1315 case REQUEST_THUMBNAIL:
1316 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "requestThumbnail");
1317 handleRequestThumbnail((IBinder)msg.obj);
1318 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1320 case CONFIGURATION_CHANGED:
1321 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "configChanged");
1322 mCurDefaultDisplayDpi = ((Configuration)msg.obj).densityDpi;
1323 handleConfigurationChanged((Configuration)msg.obj, null);
1324 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1326 case CLEAN_UP_CONTEXT:
1327 ContextCleanupInfo cci = (ContextCleanupInfo)msg.obj;
1328 cci.context.performFinalCleanup(cci.who, cci.what);
1334 handleDumpService((DumpComponentInfo)msg.obj);
1337 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "lowMemory");
1339 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1341 case ACTIVITY_CONFIGURATION_CHANGED:
1342 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityConfigChanged");
1343 handleActivityConfigurationChanged((IBinder)msg.obj);
1344 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1346 case PROFILER_CONTROL:
1347 handleProfilerControl(msg.arg1 != 0, (ProfilerControlData)msg.obj, msg.arg2);
1349 case CREATE_BACKUP_AGENT:
1350 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "backupCreateAgent");
1351 handleCreateBackupAgent((CreateBackupAgentData)msg.obj);
1352 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1354 case DESTROY_BACKUP_AGENT:
1355 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "backupDestroyAgent");
1356 handleDestroyBackupAgent((CreateBackupAgentData)msg.obj);
1357 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1360 Process.killProcess(Process.myPid());
1362 case REMOVE_PROVIDER:
1363 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "providerRemove");
1364 completeRemoveProvider((ProviderRefCount)msg.obj);
1365 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1370 case DISPATCH_PACKAGE_BROADCAST:
1371 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "broadcastPackage");
1372 handleDispatchPackageBroadcast(msg.arg1, (String[])msg.obj);
1373 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1375 case SCHEDULE_CRASH:
1376 throw new RemoteServiceException((String)msg.obj);
1378 handleDumpHeap(msg.arg1 != 0, (DumpHeapData)msg.obj);
1381 handleDumpActivity((DumpComponentInfo)msg.obj);
1384 handleDumpProvider((DumpComponentInfo)msg.obj);
1387 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "sleeping");
1388 handleSleeping((IBinder)msg.obj, msg.arg1 != 0);
1389 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1391 case SET_CORE_SETTINGS:
1392 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "setCoreSettings");
1393 handleSetCoreSettings((Bundle) msg.obj);
1394 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1396 case UPDATE_PACKAGE_COMPATIBILITY_INFO:
1397 handleUpdatePackageCompatibilityInfo((UpdateCompatibilityData)msg.obj);
1400 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "trimMemory");
1401 handleTrimMemory(msg.arg1);
1402 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1404 case UNSTABLE_PROVIDER_DIED:
1405 handleUnstableProviderDied((IBinder)msg.obj, false);
1407 case REQUEST_ASSIST_CONTEXT_EXTRAS:
1408 handleRequestAssistContextExtras((RequestAssistContextExtras)msg.obj);
1410 case TRANSLUCENT_CONVERSION_COMPLETE:
1411 handleTranslucentConversionComplete((IBinder)msg.obj, msg.arg1 == 1);
1413 case INSTALL_PROVIDER:
1414 handleInstallProvider((ProviderInfo) msg.obj);
1417 if (DEBUG_MESSAGES) Slog.v(TAG, "<<< done: " + codeToString(msg.what));
1420 private void maybeSnapshot() {
1421 if (mBoundApplication != null && SamplingProfilerIntegration.isEnabled()) {
1422 // convert the *private* ActivityThread.PackageInfo to *public* known
1423 // android.content.pm.PackageInfo
1424 String packageName = mBoundApplication.info.mPackageName;
1425 android.content.pm.PackageInfo packageInfo = null;
1427 Context context = getSystemContext();
1428 if(context == null) {
1429 Log.e(TAG, "cannot get a valid context");
1432 PackageManager pm = context.getPackageManager();
1434 Log.e(TAG, "cannot get a valid PackageManager");
1437 packageInfo = pm.getPackageInfo(
1438 packageName, PackageManager.GET_ACTIVITIES);
1439 } catch (NameNotFoundException e) {
1440 Log.e(TAG, "cannot get package info for " + packageName, e);
1442 SamplingProfilerIntegration.writeSnapshot(mBoundApplication.processName, packageInfo);
1447 private class Idler implements MessageQueue.IdleHandler {
1449 public final boolean queueIdle() {
1450 ActivityClientRecord a = mNewActivities;
1451 boolean stopProfiling = false;
1452 if (mBoundApplication != null && mProfiler.profileFd != null
1453 && mProfiler.autoStopProfiler) {
1454 stopProfiling = true;
1457 mNewActivities = null;
1458 IActivityManager am = ActivityManagerNative.getDefault();
1459 ActivityClientRecord prev;
1461 if (localLOGV) Slog.v(
1462 TAG, "Reporting idle of " + a +
1464 (a.activity != null && a.activity.mFinished));
1465 if (a.activity != null && !a.activity.mFinished) {
1467 am.activityIdle(a.token, a.createdConfig, stopProfiling);
1468 a.createdConfig = null;
1469 } catch (RemoteException ex) {
1475 prev.nextIdle = null;
1476 } while (a != null);
1478 if (stopProfiling) {
1479 mProfiler.stopProfiling();
1486 final class GcIdler implements MessageQueue.IdleHandler {
1488 public final boolean queueIdle() {
1494 public static ActivityThread currentActivityThread() {
1495 return sCurrentActivityThread;
1498 public static String currentPackageName() {
1499 ActivityThread am = currentActivityThread();
1500 return (am != null && am.mBoundApplication != null)
1501 ? am.mBoundApplication.appInfo.packageName : null;
1504 public static String currentProcessName() {
1505 ActivityThread am = currentActivityThread();
1506 return (am != null && am.mBoundApplication != null)
1507 ? am.mBoundApplication.processName : null;
1510 public static Application currentApplication() {
1511 ActivityThread am = currentActivityThread();
1512 return am != null ? am.mInitialApplication : null;
1515 public static IPackageManager getPackageManager() {
1516 if (sPackageManager != null) {
1517 //Slog.v("PackageManager", "returning cur default = " + sPackageManager);
1518 return sPackageManager;
1520 IBinder b = ServiceManager.getService("package");
1521 //Slog.v("PackageManager", "default service binder = " + b);
1522 sPackageManager = IPackageManager.Stub.asInterface(b);
1523 //Slog.v("PackageManager", "default service = " + sPackageManager);
1524 return sPackageManager;
1527 private Configuration mMainThreadConfig = new Configuration();
1528 Configuration applyConfigCompatMainThread(int displayDensity, Configuration config,
1529 CompatibilityInfo compat) {
1530 if (config == null) {
1533 if (!compat.supportsScreen()) {
1534 mMainThreadConfig.setTo(config);
1535 config = mMainThreadConfig;
1536 compat.applyToConfiguration(displayDensity, config);
1542 * Creates the top level resources for the given package.
1544 Resources getTopLevelResources(String resDir,
1545 int displayId, Configuration overrideConfiguration,
1546 LoadedApk pkgInfo) {
1547 return mResourcesManager.getTopLevelResources(resDir, displayId, overrideConfiguration,
1548 pkgInfo.getCompatibilityInfo(), null);
1551 final Handler getHandler() {
1555 public final LoadedApk getPackageInfo(String packageName, CompatibilityInfo compatInfo,
1557 return getPackageInfo(packageName, compatInfo, flags, UserHandle.myUserId());
1560 public final LoadedApk getPackageInfo(String packageName, CompatibilityInfo compatInfo,
1561 int flags, int userId) {
1562 synchronized (mResourcesManager) {
1563 WeakReference<LoadedApk> ref;
1564 if ((flags&Context.CONTEXT_INCLUDE_CODE) != 0) {
1565 ref = mPackages.get(packageName);
1567 ref = mResourcePackages.get(packageName);
1569 LoadedApk packageInfo = ref != null ? ref.get() : null;
1570 //Slog.i(TAG, "getPackageInfo " + packageName + ": " + packageInfo);
1571 //if (packageInfo != null) Slog.i(TAG, "isUptoDate " + packageInfo.mResDir
1572 // + ": " + packageInfo.mResources.getAssets().isUpToDate());
1573 if (packageInfo != null && (packageInfo.mResources == null
1574 || packageInfo.mResources.getAssets().isUpToDate())) {
1575 if (packageInfo.isSecurityViolation()
1576 && (flags&Context.CONTEXT_IGNORE_SECURITY) == 0) {
1577 throw new SecurityException(
1578 "Requesting code from " + packageName
1579 + " to be run in process "
1580 + mBoundApplication.processName
1581 + "/" + mBoundApplication.appInfo.uid);
1587 ApplicationInfo ai = null;
1589 ai = getPackageManager().getApplicationInfo(packageName,
1590 PackageManager.GET_SHARED_LIBRARY_FILES, userId);
1591 } catch (RemoteException e) {
1596 return getPackageInfo(ai, compatInfo, flags);
1602 public final LoadedApk getPackageInfo(ApplicationInfo ai, CompatibilityInfo compatInfo,
1604 boolean includeCode = (flags&Context.CONTEXT_INCLUDE_CODE) != 0;
1605 boolean securityViolation = includeCode && ai.uid != 0
1606 && ai.uid != Process.SYSTEM_UID && (mBoundApplication != null
1607 ? !UserHandle.isSameApp(ai.uid, mBoundApplication.appInfo.uid)
1609 if ((flags&(Context.CONTEXT_INCLUDE_CODE
1610 |Context.CONTEXT_IGNORE_SECURITY))
1611 == Context.CONTEXT_INCLUDE_CODE) {
1612 if (securityViolation) {
1613 String msg = "Requesting code from " + ai.packageName
1614 + " (with uid " + ai.uid + ")";
1615 if (mBoundApplication != null) {
1616 msg = msg + " to be run in process "
1617 + mBoundApplication.processName + " (with uid "
1618 + mBoundApplication.appInfo.uid + ")";
1620 throw new SecurityException(msg);
1623 return getPackageInfo(ai, compatInfo, null, securityViolation, includeCode);
1626 public final LoadedApk getPackageInfoNoCheck(ApplicationInfo ai,
1627 CompatibilityInfo compatInfo) {
1628 return getPackageInfo(ai, compatInfo, null, false, true);
1631 public final LoadedApk peekPackageInfo(String packageName, boolean includeCode) {
1632 synchronized (mResourcesManager) {
1633 WeakReference<LoadedApk> ref;
1635 ref = mPackages.get(packageName);
1637 ref = mResourcePackages.get(packageName);
1639 return ref != null ? ref.get() : null;
1643 private LoadedApk getPackageInfo(ApplicationInfo aInfo, CompatibilityInfo compatInfo,
1644 ClassLoader baseLoader, boolean securityViolation, boolean includeCode) {
1645 synchronized (mResourcesManager) {
1646 WeakReference<LoadedApk> ref;
1648 ref = mPackages.get(aInfo.packageName);
1650 ref = mResourcePackages.get(aInfo.packageName);
1652 LoadedApk packageInfo = ref != null ? ref.get() : null;
1653 if (packageInfo == null || (packageInfo.mResources != null
1654 && !packageInfo.mResources.getAssets().isUpToDate())) {
1655 if (localLOGV) Slog.v(TAG, (includeCode ? "Loading code package "
1656 : "Loading resource-only package ") + aInfo.packageName
1657 + " (in " + (mBoundApplication != null
1658 ? mBoundApplication.processName : null)
1661 new LoadedApk(this, aInfo, compatInfo, baseLoader,
1662 securityViolation, includeCode &&
1663 (aInfo.flags&ApplicationInfo.FLAG_HAS_CODE) != 0);
1665 mPackages.put(aInfo.packageName,
1666 new WeakReference<LoadedApk>(packageInfo));
1668 mResourcePackages.put(aInfo.packageName,
1669 new WeakReference<LoadedApk>(packageInfo));
1677 mResourcesManager = ResourcesManager.getInstance();
1680 public ApplicationThread getApplicationThread()
1685 public Instrumentation getInstrumentation()
1687 return mInstrumentation;
1690 public boolean isProfiling() {
1691 return mProfiler != null && mProfiler.profileFile != null
1692 && mProfiler.profileFd == null;
1695 public String getProfileFilePath() {
1696 return mProfiler.profileFile;
1699 public Looper getLooper() {
1703 public Application getApplication() {
1704 return mInitialApplication;
1707 public String getProcessName() {
1708 return mBoundApplication.processName;
1711 public ContextImpl getSystemContext() {
1712 synchronized (this) {
1713 if (mSystemContext == null) {
1714 mSystemContext = ContextImpl.createSystemContext(this);
1716 return mSystemContext;
1720 public void installSystemApplicationInfo(ApplicationInfo info) {
1721 synchronized (this) {
1722 getSystemContext().installSystemApplicationInfo(info);
1724 // give ourselves a default profiler
1725 mProfiler = new Profiler();
1729 void ensureJitEnabled() {
1732 dalvik.system.VMRuntime.getRuntime().startJitCompilation();
1736 void scheduleGcIdler() {
1737 if (!mGcIdlerScheduled) {
1738 mGcIdlerScheduled = true;
1739 Looper.myQueue().addIdleHandler(mGcIdler);
1741 mH.removeMessages(H.GC_WHEN_IDLE);
1744 void unscheduleGcIdler() {
1745 if (mGcIdlerScheduled) {
1746 mGcIdlerScheduled = false;
1747 Looper.myQueue().removeIdleHandler(mGcIdler);
1749 mH.removeMessages(H.GC_WHEN_IDLE);
1752 void doGcIfNeeded() {
1753 mGcIdlerScheduled = false;
1754 final long now = SystemClock.uptimeMillis();
1755 //Slog.i(TAG, "**** WE MIGHT WANT TO GC: then=" + Binder.getLastGcTime()
1756 // + "m now=" + now);
1757 if ((BinderInternal.getLastGcTime()+MIN_TIME_BETWEEN_GCS) < now) {
1758 //Slog.i(TAG, "**** WE DO, WE DO WANT TO GC!");
1759 BinderInternal.forceGc("bg");
1763 private static final String HEAP_FULL_COLUMN
1764 = "%13s %8s %8s %8s %8s %8s %8s %8s %8s %8s %8s";
1765 private static final String HEAP_COLUMN
1766 = "%13s %8s %8s %8s %8s %8s %8s %8s";
1768 // Formatting for checkin service - update version if row format changes
1769 private static final int ACTIVITY_THREAD_CHECKIN_VERSION = 3;
1771 static void printRow(PrintWriter pw, String format, Object...objs) {
1772 pw.println(String.format(format, objs));
1775 public static void dumpMemInfoTable(PrintWriter pw, Debug.MemoryInfo memInfo, boolean checkin,
1776 boolean dumpFullInfo, boolean dumpDalvik, int pid, String processName,
1777 long nativeMax, long nativeAllocated, long nativeFree,
1778 long dalvikMax, long dalvikAllocated, long dalvikFree) {
1780 // For checkin, we print one long comma-separated list of values
1782 // NOTE: if you change anything significant below, also consider changing
1783 // ACTIVITY_THREAD_CHECKIN_VERSION.
1786 pw.print(ACTIVITY_THREAD_CHECKIN_VERSION); pw.print(',');
1787 pw.print(pid); pw.print(',');
1788 pw.print(processName); pw.print(',');
1791 pw.print(nativeMax); pw.print(',');
1792 pw.print(dalvikMax); pw.print(',');
1794 pw.print(nativeMax + dalvikMax); pw.print(',');
1796 // Heap info - allocated
1797 pw.print(nativeAllocated); pw.print(',');
1798 pw.print(dalvikAllocated); pw.print(',');
1800 pw.print(nativeAllocated + dalvikAllocated); pw.print(',');
1803 pw.print(nativeFree); pw.print(',');
1804 pw.print(dalvikFree); pw.print(',');
1806 pw.print(nativeFree + dalvikFree); pw.print(',');
1808 // Heap info - proportional set size
1809 pw.print(memInfo.nativePss); pw.print(',');
1810 pw.print(memInfo.dalvikPss); pw.print(',');
1811 pw.print(memInfo.otherPss); pw.print(',');
1812 pw.print(memInfo.getTotalPss()); pw.print(',');
1814 // Heap info - swappable set size
1815 pw.print(memInfo.nativeSwappablePss); pw.print(',');
1816 pw.print(memInfo.dalvikSwappablePss); pw.print(',');
1817 pw.print(memInfo.otherSwappablePss); pw.print(',');
1818 pw.print(memInfo.getTotalSwappablePss()); pw.print(',');
1820 // Heap info - shared dirty
1821 pw.print(memInfo.nativeSharedDirty); pw.print(',');
1822 pw.print(memInfo.dalvikSharedDirty); pw.print(',');
1823 pw.print(memInfo.otherSharedDirty); pw.print(',');
1824 pw.print(memInfo.getTotalSharedDirty()); pw.print(',');
1826 // Heap info - shared clean
1827 pw.print(memInfo.nativeSharedClean); pw.print(',');
1828 pw.print(memInfo.dalvikSharedClean); pw.print(',');
1829 pw.print(memInfo.otherSharedClean); pw.print(',');
1830 pw.print(memInfo.getTotalSharedClean()); pw.print(',');
1832 // Heap info - private Dirty
1833 pw.print(memInfo.nativePrivateDirty); pw.print(',');
1834 pw.print(memInfo.dalvikPrivateDirty); pw.print(',');
1835 pw.print(memInfo.otherPrivateDirty); pw.print(',');
1836 pw.print(memInfo.getTotalPrivateDirty()); pw.print(',');
1838 // Heap info - private Clean
1839 pw.print(memInfo.nativePrivateClean); pw.print(',');
1840 pw.print(memInfo.dalvikPrivateClean); pw.print(',');
1841 pw.print(memInfo.otherPrivateClean); pw.print(',');
1842 pw.print(memInfo.getTotalPrivateClean()); pw.print(',');
1844 // Heap info - other areas
1845 for (int i=0; i<Debug.MemoryInfo.NUM_OTHER_STATS; i++) {
1846 pw.print(Debug.MemoryInfo.getOtherLabel(i)); pw.print(',');
1847 pw.print(memInfo.getOtherPss(i)); pw.print(',');
1848 pw.print(memInfo.getOtherSwappablePss(i)); pw.print(',');
1849 pw.print(memInfo.getOtherSharedDirty(i)); pw.print(',');
1850 pw.print(memInfo.getOtherSharedClean(i)); pw.print(',');
1851 pw.print(memInfo.getOtherPrivateDirty(i)); pw.print(',');
1852 pw.print(memInfo.getOtherPrivateClean(i)); pw.print(',');
1857 // otherwise, show human-readable format
1859 printRow(pw, HEAP_FULL_COLUMN, "", "Pss", "Pss", "Shared", "Private",
1860 "Shared", "Private", "Swapped", "Heap", "Heap", "Heap");
1861 printRow(pw, HEAP_FULL_COLUMN, "", "Total", "Clean", "Dirty", "Dirty",
1862 "Clean", "Clean", "Dirty", "Size", "Alloc", "Free");
1863 printRow(pw, HEAP_FULL_COLUMN, "", "------", "------", "------", "------",
1864 "------", "------", "------", "------", "------", "------");
1865 printRow(pw, HEAP_FULL_COLUMN, "Native Heap", memInfo.nativePss,
1866 memInfo.nativeSwappablePss, memInfo.nativeSharedDirty,
1867 memInfo.nativePrivateDirty, memInfo.nativeSharedClean,
1868 memInfo.nativePrivateClean, memInfo.nativeSwappedOut,
1869 nativeMax, nativeAllocated, nativeFree);
1870 printRow(pw, HEAP_FULL_COLUMN, "Dalvik Heap", memInfo.dalvikPss,
1871 memInfo.dalvikSwappablePss, memInfo.dalvikSharedDirty,
1872 memInfo.dalvikPrivateDirty, memInfo.dalvikSharedClean,
1873 memInfo.dalvikPrivateClean, memInfo.dalvikSwappedOut,
1874 dalvikMax, dalvikAllocated, dalvikFree);
1876 printRow(pw, HEAP_COLUMN, "", "Pss", "Private",
1877 "Private", "Swapped", "Heap", "Heap", "Heap");
1878 printRow(pw, HEAP_COLUMN, "", "Total", "Dirty",
1879 "Clean", "Dirty", "Size", "Alloc", "Free");
1880 printRow(pw, HEAP_COLUMN, "", "------", "------", "------",
1881 "------", "------", "------", "------", "------");
1882 printRow(pw, HEAP_COLUMN, "Native Heap", memInfo.nativePss,
1883 memInfo.nativePrivateDirty,
1884 memInfo.nativePrivateClean, memInfo.nativeSwappedOut,
1885 nativeMax, nativeAllocated, nativeFree);
1886 printRow(pw, HEAP_COLUMN, "Dalvik Heap", memInfo.dalvikPss,
1887 memInfo.dalvikPrivateDirty,
1888 memInfo.dalvikPrivateClean, memInfo.dalvikSwappedOut,
1889 dalvikMax, dalvikAllocated, dalvikFree);
1892 int otherPss = memInfo.otherPss;
1893 int otherSwappablePss = memInfo.otherSwappablePss;
1894 int otherSharedDirty = memInfo.otherSharedDirty;
1895 int otherPrivateDirty = memInfo.otherPrivateDirty;
1896 int otherSharedClean = memInfo.otherSharedClean;
1897 int otherPrivateClean = memInfo.otherPrivateClean;
1898 int otherSwappedOut = memInfo.otherSwappedOut;
1900 for (int i=0; i<Debug.MemoryInfo.NUM_OTHER_STATS; i++) {
1901 final int myPss = memInfo.getOtherPss(i);
1902 final int mySwappablePss = memInfo.getOtherSwappablePss(i);
1903 final int mySharedDirty = memInfo.getOtherSharedDirty(i);
1904 final int myPrivateDirty = memInfo.getOtherPrivateDirty(i);
1905 final int mySharedClean = memInfo.getOtherSharedClean(i);
1906 final int myPrivateClean = memInfo.getOtherPrivateClean(i);
1907 final int mySwappedOut = memInfo.getOtherSwappedOut(i);
1908 if (myPss != 0 || mySharedDirty != 0 || myPrivateDirty != 0
1909 || mySharedClean != 0 || myPrivateClean != 0 || mySwappedOut != 0) {
1911 printRow(pw, HEAP_FULL_COLUMN, Debug.MemoryInfo.getOtherLabel(i),
1912 myPss, mySwappablePss, mySharedDirty, myPrivateDirty,
1913 mySharedClean, myPrivateClean, mySwappedOut, "", "", "");
1915 printRow(pw, HEAP_COLUMN, Debug.MemoryInfo.getOtherLabel(i),
1916 myPss, myPrivateDirty,
1917 myPrivateClean, mySwappedOut, "", "", "");
1920 otherSwappablePss -= mySwappablePss;
1921 otherSharedDirty -= mySharedDirty;
1922 otherPrivateDirty -= myPrivateDirty;
1923 otherSharedClean -= mySharedClean;
1924 otherPrivateClean -= myPrivateClean;
1925 otherSwappedOut -= mySwappedOut;
1930 printRow(pw, HEAP_FULL_COLUMN, "Unknown", otherPss, otherSwappablePss,
1931 otherSharedDirty, otherPrivateDirty, otherSharedClean, otherPrivateClean,
1932 otherSwappedOut, "", "", "");
1933 printRow(pw, HEAP_FULL_COLUMN, "TOTAL", memInfo.getTotalPss(),
1934 memInfo.getTotalSwappablePss(),
1935 memInfo.getTotalSharedDirty(), memInfo.getTotalPrivateDirty(),
1936 memInfo.getTotalSharedClean(), memInfo.getTotalPrivateClean(),
1937 memInfo.getTotalSwappedOut(), nativeMax+dalvikMax,
1938 nativeAllocated+dalvikAllocated, nativeFree+dalvikFree);
1940 printRow(pw, HEAP_COLUMN, "Unknown", otherPss,
1941 otherPrivateDirty, otherPrivateClean, otherSwappedOut,
1943 printRow(pw, HEAP_COLUMN, "TOTAL", memInfo.getTotalPss(),
1944 memInfo.getTotalPrivateDirty(),
1945 memInfo.getTotalPrivateClean(),
1946 memInfo.getTotalSwappedOut(),
1947 nativeMax+dalvikMax,
1948 nativeAllocated+dalvikAllocated, nativeFree+dalvikFree);
1953 pw.println(" Dalvik Details");
1955 for (int i=Debug.MemoryInfo.NUM_OTHER_STATS;
1956 i<Debug.MemoryInfo.NUM_OTHER_STATS + Debug.MemoryInfo.NUM_DVK_STATS; i++) {
1957 final int myPss = memInfo.getOtherPss(i);
1958 final int mySwappablePss = memInfo.getOtherSwappablePss(i);
1959 final int mySharedDirty = memInfo.getOtherSharedDirty(i);
1960 final int myPrivateDirty = memInfo.getOtherPrivateDirty(i);
1961 final int mySharedClean = memInfo.getOtherSharedClean(i);
1962 final int myPrivateClean = memInfo.getOtherPrivateClean(i);
1963 final int mySwappedOut = memInfo.getOtherSwappedOut(i);
1964 if (myPss != 0 || mySharedDirty != 0 || myPrivateDirty != 0
1965 || mySharedClean != 0 || myPrivateClean != 0) {
1967 printRow(pw, HEAP_FULL_COLUMN, Debug.MemoryInfo.getOtherLabel(i),
1968 myPss, mySwappablePss, mySharedDirty, myPrivateDirty,
1969 mySharedClean, myPrivateClean, mySwappedOut, "", "", "");
1971 printRow(pw, HEAP_COLUMN, Debug.MemoryInfo.getOtherLabel(i),
1972 myPss, myPrivateDirty,
1973 myPrivateClean, mySwappedOut, "", "", "");
1980 public void registerOnActivityPausedListener(Activity activity,
1981 OnActivityPausedListener listener) {
1982 synchronized (mOnPauseListeners) {
1983 ArrayList<OnActivityPausedListener> list = mOnPauseListeners.get(activity);
1985 list = new ArrayList<OnActivityPausedListener>();
1986 mOnPauseListeners.put(activity, list);
1992 public void unregisterOnActivityPausedListener(Activity activity,
1993 OnActivityPausedListener listener) {
1994 synchronized (mOnPauseListeners) {
1995 ArrayList<OnActivityPausedListener> list = mOnPauseListeners.get(activity);
1997 list.remove(listener);
2002 public final ActivityInfo resolveActivityInfo(Intent intent) {
2003 ActivityInfo aInfo = intent.resolveActivityInfo(
2004 mInitialApplication.getPackageManager(), PackageManager.GET_SHARED_LIBRARY_FILES);
2005 if (aInfo == null) {
2006 // Throw an exception.
2007 Instrumentation.checkStartActivityResult(
2008 ActivityManager.START_CLASS_NOT_FOUND, intent);
2013 public final Activity startActivityNow(Activity parent, String id,
2014 Intent intent, ActivityInfo activityInfo, IBinder token, Bundle state,
2015 Activity.NonConfigurationInstances lastNonConfigurationInstances) {
2016 ActivityClientRecord r = new ActivityClientRecord();
2023 r.activityInfo = activityInfo;
2024 r.lastNonConfigurationInstances = lastNonConfigurationInstances;
2026 ComponentName compname = intent.getComponent();
2028 if (compname != null) {
2029 name = compname.toShortString();
2031 name = "(Intent " + intent + ").getComponent() returned null";
2033 Slog.v(TAG, "Performing launch: action=" + intent.getAction()
2035 + ", token=" + token);
2037 return performLaunchActivity(r, null);
2040 public final Activity getActivity(IBinder token) {
2041 return mActivities.get(token).activity;
2044 public final void sendActivityResult(
2045 IBinder token, String id, int requestCode,
2046 int resultCode, Intent data) {
2047 if (DEBUG_RESULTS) Slog.v(TAG, "sendActivityResult: id=" + id
2048 + " req=" + requestCode + " res=" + resultCode + " data=" + data);
2049 ArrayList<ResultInfo> list = new ArrayList<ResultInfo>();
2050 list.add(new ResultInfo(id, requestCode, resultCode, data));
2051 mAppThread.scheduleSendResult(token, list);
2054 private void sendMessage(int what, Object obj) {
2055 sendMessage(what, obj, 0, 0, false);
2058 private void sendMessage(int what, Object obj, int arg1) {
2059 sendMessage(what, obj, arg1, 0, false);
2062 private void sendMessage(int what, Object obj, int arg1, int arg2) {
2063 sendMessage(what, obj, arg1, arg2, false);
2066 private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
2067 if (DEBUG_MESSAGES) Slog.v(
2068 TAG, "SCHEDULE " + what + " " + mH.codeToString(what)
2069 + ": " + arg1 + " / " + obj);
2070 Message msg = Message.obtain();
2076 msg.setAsynchronous(true);
2078 mH.sendMessage(msg);
2081 final void scheduleContextCleanup(ContextImpl context, String who,
2083 ContextCleanupInfo cci = new ContextCleanupInfo();
2084 cci.context = context;
2087 sendMessage(H.CLEAN_UP_CONTEXT, cci);
2090 private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
2091 // System.out.println("##### [" + System.currentTimeMillis() + "] ActivityThread.performLaunchActivity(" + r + ")");
2093 ActivityInfo aInfo = r.activityInfo;
2094 if (r.packageInfo == null) {
2095 r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
2096 Context.CONTEXT_INCLUDE_CODE);
2099 ComponentName component = r.intent.getComponent();
2100 if (component == null) {
2101 component = r.intent.resolveActivity(
2102 mInitialApplication.getPackageManager());
2103 r.intent.setComponent(component);
2106 if (r.activityInfo.targetActivity != null) {
2107 component = new ComponentName(r.activityInfo.packageName,
2108 r.activityInfo.targetActivity);
2111 Activity activity = null;
2113 java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
2114 activity = mInstrumentation.newActivity(
2115 cl, component.getClassName(), r.intent);
2116 StrictMode.incrementExpectedActivityCount(activity.getClass());
2117 r.intent.setExtrasClassLoader(cl);
2118 if (r.state != null) {
2119 r.state.setClassLoader(cl);
2121 } catch (Exception e) {
2122 if (!mInstrumentation.onException(activity, e)) {
2123 throw new RuntimeException(
2124 "Unable to instantiate activity " + component
2125 + ": " + e.toString(), e);
2130 Application app = r.packageInfo.makeApplication(false, mInstrumentation);
2132 if (localLOGV) Slog.v(TAG, "Performing launch of " + r);
2133 if (localLOGV) Slog.v(
2134 TAG, r + ": app=" + app
2135 + ", appName=" + app.getPackageName()
2136 + ", pkg=" + r.packageInfo.getPackageName()
2137 + ", comp=" + r.intent.getComponent().toShortString()
2138 + ", dir=" + r.packageInfo.getAppDir());
2140 if (activity != null) {
2141 Context appContext = createBaseContextForActivity(r, activity);
2142 CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
2143 Configuration config = new Configuration(mCompatConfiguration);
2144 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "
2145 + r.activityInfo.name + " with config " + config);
2146 activity.attach(appContext, this, getInstrumentation(), r.token,
2147 r.ident, app, r.intent, r.activityInfo, title, r.parent,
2148 r.embeddedID, r.lastNonConfigurationInstances, config);
2150 if (customIntent != null) {
2151 activity.mIntent = customIntent;
2153 r.lastNonConfigurationInstances = null;
2154 activity.mStartedActivity = false;
2155 int theme = r.activityInfo.getThemeResource();
2157 activity.setTheme(theme);
2160 activity.mCalled = false;
2161 mInstrumentation.callActivityOnCreate(activity, r.state);
2162 if (!activity.mCalled) {
2163 throw new SuperNotCalledException(
2164 "Activity " + r.intent.getComponent().toShortString() +
2165 " did not call through to super.onCreate()");
2167 r.activity = activity;
2169 if (!r.activity.mFinished) {
2170 activity.performStart();
2173 if (!r.activity.mFinished) {
2174 if (r.state != null) {
2175 mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
2178 if (!r.activity.mFinished) {
2179 activity.mCalled = false;
2180 mInstrumentation.callActivityOnPostCreate(activity, r.state);
2181 if (!activity.mCalled) {
2182 throw new SuperNotCalledException(
2183 "Activity " + r.intent.getComponent().toShortString() +
2184 " did not call through to super.onPostCreate()");
2190 mActivities.put(r.token, r);
2192 } catch (SuperNotCalledException e) {
2195 } catch (Exception e) {
2196 if (!mInstrumentation.onException(activity, e)) {
2197 throw new RuntimeException(
2198 "Unable to start activity " + component
2199 + ": " + e.toString(), e);
2206 private Context createBaseContextForActivity(ActivityClientRecord r,
2207 final Activity activity) {
2208 ContextImpl appContext = ContextImpl.createActivityContext(this, r.packageInfo, r.token);
2209 appContext.setOuterContext(activity);
2210 Context baseContext = appContext;
2212 final DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance();
2214 IActivityContainer container =
2215 ActivityManagerNative.getDefault().getEnclosingActivityContainer(r.token);
2216 final int displayId =
2217 container == null ? Display.DEFAULT_DISPLAY : container.getDisplayId();
2218 if (displayId > Display.DEFAULT_DISPLAY) {
2219 Display display = dm.getRealDisplay(displayId, r.token);
2220 baseContext = appContext.createDisplayContext(display);
2222 } catch (RemoteException e) {
2225 // For debugging purposes, if the activity's package name contains the value of
2226 // the "debug.use-second-display" system property as a substring, then show
2227 // its content on a secondary display if there is one.
2228 String pkgName = SystemProperties.get("debug.second-display.pkg");
2229 if (pkgName != null && !pkgName.isEmpty()
2230 && r.packageInfo.mPackageName.contains(pkgName)) {
2231 for (int displayId : dm.getDisplayIds()) {
2232 if (displayId != Display.DEFAULT_DISPLAY) {
2233 Display display = dm.getRealDisplay(displayId, r.token);
2234 baseContext = appContext.createDisplayContext(display);
2242 private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
2243 // If we are getting ready to gc after going to the background, well
2244 // we are back active so skip it.
2245 unscheduleGcIdler();
2247 if (r.profileFd != null) {
2248 mProfiler.setProfiler(r.profileFile, r.profileFd);
2249 mProfiler.startProfiling();
2250 mProfiler.autoStopProfiler = r.autoStopProfiler;
2253 // Make sure we are running with the most recent config.
2254 handleConfigurationChanged(null, null);
2256 if (localLOGV) Slog.v(
2257 TAG, "Handling launch of " + r);
2258 Activity a = performLaunchActivity(r, customIntent);
2261 r.createdConfig = new Configuration(mConfiguration);
2262 Bundle oldState = r.state;
2263 handleResumeActivity(r.token, false, r.isForward,
2264 !r.activity.mFinished && !r.startsNotResumed);
2266 if (!r.activity.mFinished && r.startsNotResumed) {
2267 // The activity manager actually wants this one to start out
2268 // paused, because it needs to be visible but isn't in the
2269 // foreground. We accomplish this by going through the
2270 // normal startup (because activities expect to go through
2271 // onResume() the first time they run, before their window
2272 // is displayed), and then pausing it. However, in this case
2273 // we do -not- need to do the full pause cycle (of freezing
2274 // and such) because the activity manager assumes it can just
2275 // retain the current state it has.
2277 r.activity.mCalled = false;
2278 mInstrumentation.callActivityOnPause(r.activity);
2279 // We need to keep around the original state, in case
2280 // we need to be created again. But we only do this
2281 // for pre-Honeycomb apps, which always save their state
2282 // when pausing, so we can not have them save their state
2283 // when restarting from a paused state. For HC and later,
2284 // we want to (and can) let the state be saved as the normal
2285 // part of stopping the activity.
2286 if (r.isPreHoneycomb()) {
2289 if (!r.activity.mCalled) {
2290 throw new SuperNotCalledException(
2291 "Activity " + r.intent.getComponent().toShortString() +
2292 " did not call through to super.onPause()");
2295 } catch (SuperNotCalledException e) {
2298 } catch (Exception e) {
2299 if (!mInstrumentation.onException(r.activity, e)) {
2300 throw new RuntimeException(
2301 "Unable to pause activity "
2302 + r.intent.getComponent().toShortString()
2303 + ": " + e.toString(), e);
2309 // If there was an error, for any reason, tell the activity
2310 // manager to stop us.
2312 ActivityManagerNative.getDefault()
2313 .finishActivity(r.token, Activity.RESULT_CANCELED, null);
2314 } catch (RemoteException ex) {
2320 private void deliverNewIntents(ActivityClientRecord r,
2321 List<Intent> intents) {
2322 final int N = intents.size();
2323 for (int i=0; i<N; i++) {
2324 Intent intent = intents.get(i);
2325 intent.setExtrasClassLoader(r.activity.getClassLoader());
2326 r.activity.mFragments.noteStateNotSaved();
2327 mInstrumentation.callActivityOnNewIntent(r.activity, intent);
2331 public final void performNewIntents(IBinder token,
2332 List<Intent> intents) {
2333 ActivityClientRecord r = mActivities.get(token);
2335 final boolean resumed = !r.paused;
2337 r.activity.mTemporaryPause = true;
2338 mInstrumentation.callActivityOnPause(r.activity);
2340 deliverNewIntents(r, intents);
2342 r.activity.performResume();
2343 r.activity.mTemporaryPause = false;
2348 private void handleNewIntent(NewIntentData data) {
2349 performNewIntents(data.token, data.intents);
2352 public void handleRequestAssistContextExtras(RequestAssistContextExtras cmd) {
2353 Bundle data = new Bundle();
2354 ActivityClientRecord r = mActivities.get(cmd.activityToken);
2356 r.activity.getApplication().dispatchOnProvideAssistData(r.activity, data);
2357 r.activity.onProvideAssistData(data);
2359 if (data.isEmpty()) {
2362 IActivityManager mgr = ActivityManagerNative.getDefault();
2364 mgr.reportAssistContextExtras(cmd.requestToken, data);
2365 } catch (RemoteException e) {
2369 public void handleTranslucentConversionComplete(IBinder token, boolean drawComplete) {
2370 ActivityClientRecord r = mActivities.get(token);
2372 r.activity.onTranslucentConversionComplete(drawComplete);
2376 public void handleInstallProvider(ProviderInfo info) {
2377 installContentProviders(mInitialApplication, Lists.newArrayList(info));
2380 private static final ThreadLocal<Intent> sCurrentBroadcastIntent = new ThreadLocal<Intent>();
2383 * Return the Intent that's currently being handled by a
2384 * BroadcastReceiver on this thread, or null if none.
2387 public static Intent getIntentBeingBroadcast() {
2388 return sCurrentBroadcastIntent.get();
2391 private void handleReceiver(ReceiverData data) {
2392 // If we are getting ready to gc after going to the background, well
2393 // we are back active so skip it.
2394 unscheduleGcIdler();
2396 String component = data.intent.getComponent().getClassName();
2398 LoadedApk packageInfo = getPackageInfoNoCheck(
2399 data.info.applicationInfo, data.compatInfo);
2401 IActivityManager mgr = ActivityManagerNative.getDefault();
2403 BroadcastReceiver receiver;
2405 java.lang.ClassLoader cl = packageInfo.getClassLoader();
2406 data.intent.setExtrasClassLoader(cl);
2407 data.setExtrasClassLoader(cl);
2408 receiver = (BroadcastReceiver)cl.loadClass(component).newInstance();
2409 } catch (Exception e) {
2410 if (DEBUG_BROADCAST) Slog.i(TAG,
2411 "Finishing failed broadcast to " + data.intent.getComponent());
2412 data.sendFinished(mgr);
2413 throw new RuntimeException(
2414 "Unable to instantiate receiver " + component
2415 + ": " + e.toString(), e);
2419 Application app = packageInfo.makeApplication(false, mInstrumentation);
2421 if (localLOGV) Slog.v(
2422 TAG, "Performing receive of " + data.intent
2424 + ", appName=" + app.getPackageName()
2425 + ", pkg=" + packageInfo.getPackageName()
2426 + ", comp=" + data.intent.getComponent().toShortString()
2427 + ", dir=" + packageInfo.getAppDir());
2429 ContextImpl context = (ContextImpl)app.getBaseContext();
2430 sCurrentBroadcastIntent.set(data.intent);
2431 receiver.setPendingResult(data);
2432 receiver.onReceive(context.getReceiverRestrictedContext(),
2434 } catch (Exception e) {
2435 if (DEBUG_BROADCAST) Slog.i(TAG,
2436 "Finishing failed broadcast to " + data.intent.getComponent());
2437 data.sendFinished(mgr);
2438 if (!mInstrumentation.onException(receiver, e)) {
2439 throw new RuntimeException(
2440 "Unable to start receiver " + component
2441 + ": " + e.toString(), e);
2444 sCurrentBroadcastIntent.set(null);
2447 if (receiver.getPendingResult() != null) {
2452 // Instantiate a BackupAgent and tell it that it's alive
2453 private void handleCreateBackupAgent(CreateBackupAgentData data) {
2454 if (DEBUG_BACKUP) Slog.v(TAG, "handleCreateBackupAgent: " + data);
2456 // Sanity check the requested target package's uid against ours
2458 PackageInfo requestedPackage = getPackageManager().getPackageInfo(
2459 data.appInfo.packageName, 0, UserHandle.myUserId());
2460 if (requestedPackage.applicationInfo.uid != Process.myUid()) {
2461 Slog.w(TAG, "Asked to instantiate non-matching package "
2462 + data.appInfo.packageName);
2465 } catch (RemoteException e) {
2466 Slog.e(TAG, "Can't reach package manager", e);
2470 // no longer idle; we have backup work to do
2471 unscheduleGcIdler();
2473 // instantiate the BackupAgent class named in the manifest
2474 LoadedApk packageInfo = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
2475 String packageName = packageInfo.mPackageName;
2476 if (packageName == null) {
2477 Slog.d(TAG, "Asked to create backup agent for nonexistent package");
2481 if (mBackupAgents.get(packageName) != null) {
2482 Slog.d(TAG, "BackupAgent " + " for " + packageName
2483 + " already exists");
2487 BackupAgent agent = null;
2488 String classname = data.appInfo.backupAgentName;
2490 // full backup operation but no app-supplied agent? use the default implementation
2491 if (classname == null && (data.backupMode == IApplicationThread.BACKUP_MODE_FULL
2492 || data.backupMode == IApplicationThread.BACKUP_MODE_RESTORE_FULL)) {
2493 classname = "android.app.backup.FullBackupAgent";
2497 IBinder binder = null;
2499 if (DEBUG_BACKUP) Slog.v(TAG, "Initializing agent class " + classname);
2501 java.lang.ClassLoader cl = packageInfo.getClassLoader();
2502 agent = (BackupAgent) cl.loadClass(classname).newInstance();
2504 // set up the agent's context
2505 ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
2506 context.setOuterContext(agent);
2507 agent.attach(context);
2510 binder = agent.onBind();
2511 mBackupAgents.put(packageName, agent);
2512 } catch (Exception e) {
2513 // If this is during restore, fail silently; otherwise go
2514 // ahead and let the user see the crash.
2515 Slog.e(TAG, "Agent threw during creation: " + e);
2516 if (data.backupMode != IApplicationThread.BACKUP_MODE_RESTORE
2517 && data.backupMode != IApplicationThread.BACKUP_MODE_RESTORE_FULL) {
2520 // falling through with 'binder' still null
2523 // tell the OS that we're live now
2525 ActivityManagerNative.getDefault().backupAgentCreated(packageName, binder);
2526 } catch (RemoteException e) {
2529 } catch (Exception e) {
2530 throw new RuntimeException("Unable to create BackupAgent "
2531 + classname + ": " + e.toString(), e);
2535 // Tear down a BackupAgent
2536 private void handleDestroyBackupAgent(CreateBackupAgentData data) {
2537 if (DEBUG_BACKUP) Slog.v(TAG, "handleDestroyBackupAgent: " + data);
2539 LoadedApk packageInfo = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
2540 String packageName = packageInfo.mPackageName;
2541 BackupAgent agent = mBackupAgents.get(packageName);
2542 if (agent != null) {
2545 } catch (Exception e) {
2546 Slog.w(TAG, "Exception thrown in onDestroy by backup agent of " + data.appInfo);
2547 e.printStackTrace();
2549 mBackupAgents.remove(packageName);
2551 Slog.w(TAG, "Attempt to destroy unknown backup agent " + data);
2555 private void handleCreateService(CreateServiceData data) {
2556 // If we are getting ready to gc after going to the background, well
2557 // we are back active so skip it.
2558 unscheduleGcIdler();
2560 LoadedApk packageInfo = getPackageInfoNoCheck(
2561 data.info.applicationInfo, data.compatInfo);
2562 Service service = null;
2564 java.lang.ClassLoader cl = packageInfo.getClassLoader();
2565 service = (Service) cl.loadClass(data.info.name).newInstance();
2566 } catch (Exception e) {
2567 if (!mInstrumentation.onException(service, e)) {
2568 throw new RuntimeException(
2569 "Unable to instantiate service " + data.info.name
2570 + ": " + e.toString(), e);
2575 if (localLOGV) Slog.v(TAG, "Creating service " + data.info.name);
2577 ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
2578 context.setOuterContext(service);
2580 Application app = packageInfo.makeApplication(false, mInstrumentation);
2581 service.attach(context, this, data.info.name, data.token, app,
2582 ActivityManagerNative.getDefault());
2584 mServices.put(data.token, service);
2586 ActivityManagerNative.getDefault().serviceDoneExecuting(
2587 data.token, 0, 0, 0);
2588 } catch (RemoteException e) {
2591 } catch (Exception e) {
2592 if (!mInstrumentation.onException(service, e)) {
2593 throw new RuntimeException(
2594 "Unable to create service " + data.info.name
2595 + ": " + e.toString(), e);
2600 private void handleBindService(BindServiceData data) {
2601 Service s = mServices.get(data.token);
2603 Slog.v(TAG, "handleBindService s=" + s + " rebind=" + data.rebind);
2606 data.intent.setExtrasClassLoader(s.getClassLoader());
2609 IBinder binder = s.onBind(data.intent);
2610 ActivityManagerNative.getDefault().publishService(
2611 data.token, data.intent, binder);
2613 s.onRebind(data.intent);
2614 ActivityManagerNative.getDefault().serviceDoneExecuting(
2615 data.token, 0, 0, 0);
2618 } catch (RemoteException ex) {
2620 } catch (Exception e) {
2621 if (!mInstrumentation.onException(s, e)) {
2622 throw new RuntimeException(
2623 "Unable to bind to service " + s
2624 + " with " + data.intent + ": " + e.toString(), e);
2630 private void handleUnbindService(BindServiceData data) {
2631 Service s = mServices.get(data.token);
2634 data.intent.setExtrasClassLoader(s.getClassLoader());
2635 boolean doRebind = s.onUnbind(data.intent);
2638 ActivityManagerNative.getDefault().unbindFinished(
2639 data.token, data.intent, doRebind);
2641 ActivityManagerNative.getDefault().serviceDoneExecuting(
2642 data.token, 0, 0, 0);
2644 } catch (RemoteException ex) {
2646 } catch (Exception e) {
2647 if (!mInstrumentation.onException(s, e)) {
2648 throw new RuntimeException(
2649 "Unable to unbind to service " + s
2650 + " with " + data.intent + ": " + e.toString(), e);
2656 private void handleDumpService(DumpComponentInfo info) {
2657 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
2659 Service s = mServices.get(info.token);
2661 PrintWriter pw = new FastPrintWriter(new FileOutputStream(
2662 info.fd.getFileDescriptor()));
2663 s.dump(info.fd.getFileDescriptor(), pw, info.args);
2667 IoUtils.closeQuietly(info.fd);
2668 StrictMode.setThreadPolicy(oldPolicy);
2672 private void handleDumpActivity(DumpComponentInfo info) {
2673 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
2675 ActivityClientRecord r = mActivities.get(info.token);
2676 if (r != null && r.activity != null) {
2677 PrintWriter pw = new FastPrintWriter(new FileOutputStream(
2678 info.fd.getFileDescriptor()));
2679 r.activity.dump(info.prefix, info.fd.getFileDescriptor(), pw, info.args);
2683 IoUtils.closeQuietly(info.fd);
2684 StrictMode.setThreadPolicy(oldPolicy);
2688 private void handleDumpProvider(DumpComponentInfo info) {
2689 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
2691 ProviderClientRecord r = mLocalProviders.get(info.token);
2692 if (r != null && r.mLocalProvider != null) {
2693 PrintWriter pw = new FastPrintWriter(new FileOutputStream(
2694 info.fd.getFileDescriptor()));
2695 r.mLocalProvider.dump(info.fd.getFileDescriptor(), pw, info.args);
2699 IoUtils.closeQuietly(info.fd);
2700 StrictMode.setThreadPolicy(oldPolicy);
2704 private void handleServiceArgs(ServiceArgsData data) {
2705 Service s = mServices.get(data.token);
2708 if (data.args != null) {
2709 data.args.setExtrasClassLoader(s.getClassLoader());
2712 if (!data.taskRemoved) {
2713 res = s.onStartCommand(data.args, data.flags, data.startId);
2715 s.onTaskRemoved(data.args);
2716 res = Service.START_TASK_REMOVED_COMPLETE;
2719 QueuedWork.waitToFinish();
2722 ActivityManagerNative.getDefault().serviceDoneExecuting(
2723 data.token, 1, data.startId, res);
2724 } catch (RemoteException e) {
2728 } catch (Exception e) {
2729 if (!mInstrumentation.onException(s, e)) {
2730 throw new RuntimeException(
2731 "Unable to start service " + s
2732 + " with " + data.args + ": " + e.toString(), e);
2738 private void handleStopService(IBinder token) {
2739 Service s = mServices.remove(token);
2742 if (localLOGV) Slog.v(TAG, "Destroying service " + s);
2744 Context context = s.getBaseContext();
2745 if (context instanceof ContextImpl) {
2746 final String who = s.getClassName();
2747 ((ContextImpl) context).scheduleFinalCleanup(who, "Service");
2750 QueuedWork.waitToFinish();
2753 ActivityManagerNative.getDefault().serviceDoneExecuting(
2755 } catch (RemoteException e) {
2758 } catch (Exception e) {
2759 if (!mInstrumentation.onException(s, e)) {
2760 throw new RuntimeException(
2761 "Unable to stop service " + s
2762 + ": " + e.toString(), e);
2766 //Slog.i(TAG, "Running services: " + mServices);
2769 public final ActivityClientRecord performResumeActivity(IBinder token,
2770 boolean clearHide) {
2771 ActivityClientRecord r = mActivities.get(token);
2772 if (localLOGV) Slog.v(TAG, "Performing resume of " + r
2773 + " finished=" + r.activity.mFinished);
2774 if (r != null && !r.activity.mFinished) {
2776 r.hideForNow = false;
2777 r.activity.mStartedActivity = false;
2780 r.activity.mFragments.noteStateNotSaved();
2781 if (r.pendingIntents != null) {
2782 deliverNewIntents(r, r.pendingIntents);
2783 r.pendingIntents = null;
2785 if (r.pendingResults != null) {
2786 deliverResults(r, r.pendingResults);
2787 r.pendingResults = null;
2789 r.activity.performResume();
2791 EventLog.writeEvent(LOG_ON_RESUME_CALLED,
2792 UserHandle.myUserId(), r.activity.getComponentName().getClassName());
2797 } catch (Exception e) {
2798 if (!mInstrumentation.onException(r.activity, e)) {
2799 throw new RuntimeException(
2800 "Unable to resume activity "
2801 + r.intent.getComponent().toShortString()
2802 + ": " + e.toString(), e);
2809 static final void cleanUpPendingRemoveWindows(ActivityClientRecord r) {
2810 if (r.mPendingRemoveWindow != null) {
2811 r.mPendingRemoveWindowManager.removeViewImmediate(r.mPendingRemoveWindow);
2812 IBinder wtoken = r.mPendingRemoveWindow.getWindowToken();
2813 if (wtoken != null) {
2814 WindowManagerGlobal.getInstance().closeAll(wtoken,
2815 r.activity.getClass().getName(), "Activity");
2818 r.mPendingRemoveWindow = null;
2819 r.mPendingRemoveWindowManager = null;
2822 final void handleResumeActivity(IBinder token, boolean clearHide, boolean isForward,
2823 boolean reallyResume) {
2824 // If we are getting ready to gc after going to the background, well
2825 // we are back active so skip it.
2826 unscheduleGcIdler();
2828 ActivityClientRecord r = performResumeActivity(token, clearHide);
2831 final Activity a = r.activity;
2833 if (localLOGV) Slog.v(
2834 TAG, "Resume " + r + " started activity: " +
2835 a.mStartedActivity + ", hideForNow: " + r.hideForNow
2836 + ", finished: " + a.mFinished);
2838 final int forwardBit = isForward ?
2839 WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION : 0;
2841 // If the window hasn't yet been added to the window manager,
2842 // and this guy didn't finish itself or start another activity,
2843 // then go ahead and add the window.
2844 boolean willBeVisible = !a.mStartedActivity;
2845 if (!willBeVisible) {
2847 willBeVisible = ActivityManagerNative.getDefault().willActivityBeVisible(
2848 a.getActivityToken());
2849 } catch (RemoteException e) {
2852 if (r.window == null && !a.mFinished && willBeVisible) {
2853 r.window = r.activity.getWindow();
2854 View decor = r.window.getDecorView();
2855 decor.setVisibility(View.INVISIBLE);
2856 ViewManager wm = a.getWindowManager();
2857 WindowManager.LayoutParams l = r.window.getAttributes();
2859 l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
2860 l.softInputMode |= forwardBit;
2861 if (a.mVisibleFromClient) {
2862 a.mWindowAdded = true;
2863 wm.addView(decor, l);
2866 // If the window has already been added, but during resume
2867 // we started another activity, then don't yet make the
2869 } else if (!willBeVisible) {
2870 if (localLOGV) Slog.v(
2871 TAG, "Launch " + r + " mStartedActivity set");
2872 r.hideForNow = true;
2875 // Get rid of anything left hanging around.
2876 cleanUpPendingRemoveWindows(r);
2878 // The window is now visible if it has been added, we are not
2879 // simply finishing, and we are not starting another activity.
2880 if (!r.activity.mFinished && willBeVisible
2881 && r.activity.mDecor != null && !r.hideForNow) {
2882 if (r.newConfig != null) {
2883 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Resuming activity "
2884 + r.activityInfo.name + " with newConfig " + r.newConfig);
2885 performConfigurationChanged(r.activity, r.newConfig);
2886 freeTextLayoutCachesIfNeeded(r.activity.mCurrentConfig.diff(r.newConfig));
2889 if (localLOGV) Slog.v(TAG, "Resuming " + r + " with isForward="
2891 WindowManager.LayoutParams l = r.window.getAttributes();
2892 if ((l.softInputMode
2893 & WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION)
2895 l.softInputMode = (l.softInputMode
2896 & (~WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION))
2898 if (r.activity.mVisibleFromClient) {
2899 ViewManager wm = a.getWindowManager();
2900 View decor = r.window.getDecorView();
2901 wm.updateViewLayout(decor, l);
2904 r.activity.mVisibleFromServer = true;
2905 mNumVisibleActivities++;
2906 if (r.activity.mVisibleFromClient) {
2907 r.activity.makeVisible();
2911 if (!r.onlyLocalRequest) {
2912 r.nextIdle = mNewActivities;
2914 if (localLOGV) Slog.v(
2915 TAG, "Scheduling idle handler for " + r);
2916 Looper.myQueue().addIdleHandler(new Idler());
2918 r.onlyLocalRequest = false;
2920 // Tell the activity manager we have resumed.
2923 ActivityManagerNative.getDefault().activityResumed(token);
2924 } catch (RemoteException ex) {
2929 // If an exception was thrown when trying to resume, then
2930 // just end this activity.
2932 ActivityManagerNative.getDefault()
2933 .finishActivity(token, Activity.RESULT_CANCELED, null);
2934 } catch (RemoteException ex) {
2939 private int mThumbnailWidth = -1;
2940 private int mThumbnailHeight = -1;
2941 private Bitmap mAvailThumbnailBitmap = null;
2942 private Canvas mThumbnailCanvas = null;
2944 private Bitmap createThumbnailBitmap(ActivityClientRecord r) {
2945 Bitmap thumbnail = mAvailThumbnailBitmap;
2947 if (thumbnail == null) {
2948 int w = mThumbnailWidth;
2951 Resources res = r.activity.getResources();
2952 mThumbnailHeight = h =
2953 res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
2955 mThumbnailWidth = w =
2956 res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
2958 h = mThumbnailHeight;
2961 // On platforms where we don't want thumbnails, set dims to (0,0)
2962 if ((w > 0) && (h > 0)) {
2963 thumbnail = Bitmap.createBitmap(r.activity.getResources().getDisplayMetrics(),
2964 w, h, THUMBNAIL_FORMAT);
2965 thumbnail.eraseColor(0);
2969 if (thumbnail != null) {
2970 Canvas cv = mThumbnailCanvas;
2972 mThumbnailCanvas = cv = new Canvas();
2975 cv.setBitmap(thumbnail);
2976 if (!r.activity.onCreateThumbnail(thumbnail, cv)) {
2977 mAvailThumbnailBitmap = thumbnail;
2983 } catch (Exception e) {
2984 if (!mInstrumentation.onException(r.activity, e)) {
2985 throw new RuntimeException(
2986 "Unable to create thumbnail of "
2987 + r.intent.getComponent().toShortString()
2988 + ": " + e.toString(), e);
2996 private void handlePauseActivity(IBinder token, boolean finished,
2997 boolean userLeaving, int configChanges) {
2998 ActivityClientRecord r = mActivities.get(token);
3000 //Slog.v(TAG, "userLeaving=" + userLeaving + " handling pause of " + r);
3002 performUserLeavingActivity(r);
3005 r.activity.mConfigChangeFlags |= configChanges;
3006 performPauseActivity(token, finished, r.isPreHoneycomb());
3008 // Make sure any pending writes are now committed.
3009 if (r.isPreHoneycomb()) {
3010 QueuedWork.waitToFinish();
3013 // Tell the activity manager we have paused.
3015 ActivityManagerNative.getDefault().activityPaused(token);
3016 } catch (RemoteException ex) {
3021 final void performUserLeavingActivity(ActivityClientRecord r) {
3022 mInstrumentation.callActivityOnUserLeaving(r.activity);
3025 final Bundle performPauseActivity(IBinder token, boolean finished,
3026 boolean saveState) {
3027 ActivityClientRecord r = mActivities.get(token);
3028 return r != null ? performPauseActivity(r, finished, saveState) : null;
3031 final Bundle performPauseActivity(ActivityClientRecord r, boolean finished,
3032 boolean saveState) {
3034 if (r.activity.mFinished) {
3035 // If we are finishing, we won't call onResume() in certain cases.
3036 // So here we likewise don't want to call onPause() if the activity
3040 RuntimeException e = new RuntimeException(
3041 "Performing pause of activity that is not resumed: "
3042 + r.intent.getComponent().toShortString());
3043 Slog.e(TAG, e.getMessage(), e);
3045 Bundle state = null;
3047 r.activity.mFinished = true;
3050 // Next have the activity save its current state and managed dialogs...
3051 if (!r.activity.mFinished && saveState) {
3052 state = new Bundle();
3053 state.setAllowFds(false);
3054 mInstrumentation.callActivityOnSaveInstanceState(r.activity, state);
3058 r.activity.mCalled = false;
3059 mInstrumentation.callActivityOnPause(r.activity);
3060 EventLog.writeEvent(LOG_ON_PAUSE_CALLED, UserHandle.myUserId(),
3061 r.activity.getComponentName().getClassName());
3062 if (!r.activity.mCalled) {
3063 throw new SuperNotCalledException(
3064 "Activity " + r.intent.getComponent().toShortString() +
3065 " did not call through to super.onPause()");
3068 } catch (SuperNotCalledException e) {
3071 } catch (Exception e) {
3072 if (!mInstrumentation.onException(r.activity, e)) {
3073 throw new RuntimeException(
3074 "Unable to pause activity "
3075 + r.intent.getComponent().toShortString()
3076 + ": " + e.toString(), e);
3081 // Notify any outstanding on paused listeners
3082 ArrayList<OnActivityPausedListener> listeners;
3083 synchronized (mOnPauseListeners) {
3084 listeners = mOnPauseListeners.remove(r.activity);
3086 int size = (listeners != null ? listeners.size() : 0);
3087 for (int i = 0; i < size; i++) {
3088 listeners.get(i).onPaused(r.activity);
3094 final void performStopActivity(IBinder token, boolean saveState) {
3095 ActivityClientRecord r = mActivities.get(token);
3096 performStopActivityInner(r, null, false, saveState);
3099 private static class StopInfo implements Runnable {
3100 ActivityClientRecord activity;
3103 CharSequence description;
3105 @Override public void run() {
3106 // Tell activity manager we have been stopped.
3108 if (DEBUG_MEMORY_TRIM) Slog.v(TAG, "Reporting activity stopped: " + activity);
3109 ActivityManagerNative.getDefault().activityStopped(
3110 activity.token, state, thumbnail, description);
3111 } catch (RemoteException ex) {
3116 private static final class ProviderRefCount {
3117 public final IActivityManager.ContentProviderHolder holder;
3118 public final ProviderClientRecord client;
3119 public int stableCount;
3120 public int unstableCount;
3122 // When this is set, the stable and unstable ref counts are 0 and
3123 // we have a pending operation scheduled to remove the ref count
3124 // from the activity manager. On the activity manager we are still
3125 // holding an unstable ref, though it is not reflected in the counts
3127 public boolean removePending;
3129 ProviderRefCount(IActivityManager.ContentProviderHolder inHolder,
3130 ProviderClientRecord inClient, int sCount, int uCount) {
3133 stableCount = sCount;
3134 unstableCount = uCount;
3139 * Core implementation of stopping an activity. Note this is a little
3140 * tricky because the server's meaning of stop is slightly different
3141 * than our client -- for the server, stop means to save state and give
3142 * it the result when it is done, but the window may still be visible.
3143 * For the client, we want to call onStop()/onStart() to indicate when
3144 * the activity's UI visibillity changes.
3146 private void performStopActivityInner(ActivityClientRecord r,
3147 StopInfo info, boolean keepShown, boolean saveState) {
3148 if (localLOGV) Slog.v(TAG, "Performing stop of " + r);
3149 Bundle state = null;
3151 if (!keepShown && r.stopped) {
3152 if (r.activity.mFinished) {
3153 // If we are finishing, we won't call onResume() in certain
3154 // cases. So here we likewise don't want to call onStop()
3155 // if the activity isn't resumed.
3158 RuntimeException e = new RuntimeException(
3159 "Performing stop of activity that is not resumed: "
3160 + r.intent.getComponent().toShortString());
3161 Slog.e(TAG, e.getMessage(), e);
3166 // First create a thumbnail for the activity...
3167 // For now, don't create the thumbnail here; we are
3168 // doing that by doing a screen snapshot.
3169 info.thumbnail = null; //createThumbnailBitmap(r);
3170 info.description = r.activity.onCreateDescription();
3171 } catch (Exception e) {
3172 if (!mInstrumentation.onException(r.activity, e)) {
3173 throw new RuntimeException(
3174 "Unable to save state of activity "
3175 + r.intent.getComponent().toShortString()
3176 + ": " + e.toString(), e);
3181 // Next have the activity save its current state and managed dialogs...
3182 if (!r.activity.mFinished && saveState) {
3183 if (r.state == null) {
3184 state = new Bundle();
3185 state.setAllowFds(false);
3186 mInstrumentation.callActivityOnSaveInstanceState(r.activity, state);
3196 r.activity.performStop();
3197 } catch (Exception e) {
3198 if (!mInstrumentation.onException(r.activity, e)) {
3199 throw new RuntimeException(
3200 "Unable to stop activity "
3201 + r.intent.getComponent().toShortString()
3202 + ": " + e.toString(), e);
3212 private void updateVisibility(ActivityClientRecord r, boolean show) {
3213 View v = r.activity.mDecor;
3216 if (!r.activity.mVisibleFromServer) {
3217 r.activity.mVisibleFromServer = true;
3218 mNumVisibleActivities++;
3219 if (r.activity.mVisibleFromClient) {
3220 r.activity.makeVisible();
3223 if (r.newConfig != null) {
3224 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Updating activity vis "
3225 + r.activityInfo.name + " with new config " + r.newConfig);
3226 performConfigurationChanged(r.activity, r.newConfig);
3227 freeTextLayoutCachesIfNeeded(r.activity.mCurrentConfig.diff(r.newConfig));
3231 if (r.activity.mVisibleFromServer) {
3232 r.activity.mVisibleFromServer = false;
3233 mNumVisibleActivities--;
3234 v.setVisibility(View.INVISIBLE);
3240 private void handleStopActivity(IBinder token, boolean show, int configChanges) {
3241 ActivityClientRecord r = mActivities.get(token);
3242 r.activity.mConfigChangeFlags |= configChanges;
3244 StopInfo info = new StopInfo();
3245 performStopActivityInner(r, info, show, true);
3247 if (localLOGV) Slog.v(
3248 TAG, "Finishing stop of " + r + ": show=" + show
3249 + " win=" + r.window);
3251 updateVisibility(r, show);
3253 // Make sure any pending writes are now committed.
3254 if (!r.isPreHoneycomb()) {
3255 QueuedWork.waitToFinish();
3258 // Schedule the call to tell the activity manager we have
3259 // stopped. We don't do this immediately, because we want to
3260 // have a chance for any other pending work (in particular memory
3261 // trim requests) to complete before you tell the activity
3262 // manager to proceed and allow us to go fully into the background.
3264 info.state = r.state;
3268 final void performRestartActivity(IBinder token) {
3269 ActivityClientRecord r = mActivities.get(token);
3271 r.activity.performRestart();
3276 private void handleWindowVisibility(IBinder token, boolean show) {
3277 ActivityClientRecord r = mActivities.get(token);
3280 Log.w(TAG, "handleWindowVisibility: no activity for token " + token);
3284 if (!show && !r.stopped) {
3285 performStopActivityInner(r, null, show, false);
3286 } else if (show && r.stopped) {
3287 // If we are getting ready to gc after going to the background, well
3288 // we are back active so skip it.
3289 unscheduleGcIdler();
3291 r.activity.performRestart();
3294 if (r.activity.mDecor != null) {
3296 TAG, "Handle window " + r + " visibility: " + show);
3297 updateVisibility(r, show);
3301 private void handleSleeping(IBinder token, boolean sleeping) {
3302 ActivityClientRecord r = mActivities.get(token);
3305 Log.w(TAG, "handleSleeping: no activity for token " + token);
3310 if (!r.stopped && !r.isPreHoneycomb()) {
3313 r.activity.performStop();
3314 } catch (Exception e) {
3315 if (!mInstrumentation.onException(r.activity, e)) {
3316 throw new RuntimeException(
3317 "Unable to stop activity "
3318 + r.intent.getComponent().toShortString()
3319 + ": " + e.toString(), e);
3325 // Make sure any pending writes are now committed.
3326 if (!r.isPreHoneycomb()) {
3327 QueuedWork.waitToFinish();
3330 // Tell activity manager we slept.
3332 ActivityManagerNative.getDefault().activitySlept(r.token);
3333 } catch (RemoteException ex) {
3336 if (r.stopped && r.activity.mVisibleFromServer) {
3337 r.activity.performRestart();
3343 private void handleSetCoreSettings(Bundle coreSettings) {
3344 synchronized (mResourcesManager) {
3345 mCoreSettings = coreSettings;
3349 private void handleUpdatePackageCompatibilityInfo(UpdateCompatibilityData data) {
3350 LoadedApk apk = peekPackageInfo(data.pkg, false);
3352 apk.setCompatibilityInfo(data.info);
3354 apk = peekPackageInfo(data.pkg, true);
3356 apk.setCompatibilityInfo(data.info);
3358 handleConfigurationChanged(mConfiguration, data.info);
3359 WindowManagerGlobal.getInstance().reportNewConfiguration(mConfiguration);
3362 private void deliverResults(ActivityClientRecord r, List<ResultInfo> results) {
3363 final int N = results.size();
3364 for (int i=0; i<N; i++) {
3365 ResultInfo ri = results.get(i);
3367 if (ri.mData != null) {
3368 ri.mData.setExtrasClassLoader(r.activity.getClassLoader());
3370 if (DEBUG_RESULTS) Slog.v(TAG,
3371 "Delivering result to activity " + r + " : " + ri);
3372 r.activity.dispatchActivityResult(ri.mResultWho,
3373 ri.mRequestCode, ri.mResultCode, ri.mData);
3374 } catch (Exception e) {
3375 if (!mInstrumentation.onException(r.activity, e)) {
3376 throw new RuntimeException(
3377 "Failure delivering result " + ri + " to activity "
3378 + r.intent.getComponent().toShortString()
3379 + ": " + e.toString(), e);
3385 private void handleSendResult(ResultData res) {
3386 ActivityClientRecord r = mActivities.get(res.token);
3387 if (DEBUG_RESULTS) Slog.v(TAG, "Handling send result to " + r);
3389 final boolean resumed = !r.paused;
3390 if (!r.activity.mFinished && r.activity.mDecor != null
3391 && r.hideForNow && resumed) {
3392 // We had hidden the activity because it started another
3393 // one... we have gotten a result back and we are not
3394 // paused, so make sure our window is visible.
3395 updateVisibility(r, true);
3400 r.activity.mCalled = false;
3401 r.activity.mTemporaryPause = true;
3402 mInstrumentation.callActivityOnPause(r.activity);
3403 if (!r.activity.mCalled) {
3404 throw new SuperNotCalledException(
3405 "Activity " + r.intent.getComponent().toShortString()
3406 + " did not call through to super.onPause()");
3408 } catch (SuperNotCalledException e) {
3410 } catch (Exception e) {
3411 if (!mInstrumentation.onException(r.activity, e)) {
3412 throw new RuntimeException(
3413 "Unable to pause activity "
3414 + r.intent.getComponent().toShortString()
3415 + ": " + e.toString(), e);
3419 deliverResults(r, res.results);
3421 r.activity.performResume();
3422 r.activity.mTemporaryPause = false;
3427 public final ActivityClientRecord performDestroyActivity(IBinder token, boolean finishing) {
3428 return performDestroyActivity(token, finishing, 0, false);
3431 private ActivityClientRecord performDestroyActivity(IBinder token, boolean finishing,
3432 int configChanges, boolean getNonConfigInstance) {
3433 ActivityClientRecord r = mActivities.get(token);
3434 Class<? extends Activity> activityClass = null;
3435 if (localLOGV) Slog.v(TAG, "Performing finish of " + r);
3437 activityClass = r.activity.getClass();
3438 r.activity.mConfigChangeFlags |= configChanges;
3440 r.activity.mFinished = true;
3444 r.activity.mCalled = false;
3445 mInstrumentation.callActivityOnPause(r.activity);
3446 EventLog.writeEvent(LOG_ON_PAUSE_CALLED, UserHandle.myUserId(),
3447 r.activity.getComponentName().getClassName());
3448 if (!r.activity.mCalled) {
3449 throw new SuperNotCalledException(
3450 "Activity " + safeToComponentShortString(r.intent)
3451 + " did not call through to super.onPause()");
3453 } catch (SuperNotCalledException e) {
3455 } catch (Exception e) {
3456 if (!mInstrumentation.onException(r.activity, e)) {
3457 throw new RuntimeException(
3458 "Unable to pause activity "
3459 + safeToComponentShortString(r.intent)
3460 + ": " + e.toString(), e);
3467 r.activity.performStop();
3468 } catch (SuperNotCalledException e) {
3470 } catch (Exception e) {
3471 if (!mInstrumentation.onException(r.activity, e)) {
3472 throw new RuntimeException(
3473 "Unable to stop activity "
3474 + safeToComponentShortString(r.intent)
3475 + ": " + e.toString(), e);
3480 if (getNonConfigInstance) {
3482 r.lastNonConfigurationInstances
3483 = r.activity.retainNonConfigurationInstances();
3484 } catch (Exception e) {
3485 if (!mInstrumentation.onException(r.activity, e)) {
3486 throw new RuntimeException(
3487 "Unable to retain activity "
3488 + r.intent.getComponent().toShortString()
3489 + ": " + e.toString(), e);
3494 r.activity.mCalled = false;
3495 mInstrumentation.callActivityOnDestroy(r.activity);
3496 if (!r.activity.mCalled) {
3497 throw new SuperNotCalledException(
3498 "Activity " + safeToComponentShortString(r.intent) +
3499 " did not call through to super.onDestroy()");
3501 if (r.window != null) {
3502 r.window.closeAllPanels();
3504 } catch (SuperNotCalledException e) {
3506 } catch (Exception e) {
3507 if (!mInstrumentation.onException(r.activity, e)) {
3508 throw new RuntimeException(
3509 "Unable to destroy activity " + safeToComponentShortString(r.intent)
3510 + ": " + e.toString(), e);
3514 mActivities.remove(token);
3515 StrictMode.decrementExpectedActivityCount(activityClass);
3519 private static String safeToComponentShortString(Intent intent) {
3520 ComponentName component = intent.getComponent();
3521 return component == null ? "[Unknown]" : component.toShortString();
3524 private void handleDestroyActivity(IBinder token, boolean finishing,
3525 int configChanges, boolean getNonConfigInstance) {
3526 ActivityClientRecord r = performDestroyActivity(token, finishing,
3527 configChanges, getNonConfigInstance);
3529 cleanUpPendingRemoveWindows(r);
3530 WindowManager wm = r.activity.getWindowManager();
3531 View v = r.activity.mDecor;
3533 if (r.activity.mVisibleFromServer) {
3534 mNumVisibleActivities--;
3536 IBinder wtoken = v.getWindowToken();
3537 if (r.activity.mWindowAdded) {
3538 if (r.onlyLocalRequest) {
3539 // Hold off on removing this until the new activity's
3540 // window is being added.
3541 r.mPendingRemoveWindow = v;
3542 r.mPendingRemoveWindowManager = wm;
3544 wm.removeViewImmediate(v);
3547 if (wtoken != null && r.mPendingRemoveWindow == null) {
3548 WindowManagerGlobal.getInstance().closeAll(wtoken,
3549 r.activity.getClass().getName(), "Activity");
3551 r.activity.mDecor = null;
3553 if (r.mPendingRemoveWindow == null) {
3554 // If we are delaying the removal of the activity window, then
3555 // we can't clean up all windows here. Note that we can't do
3556 // so later either, which means any windows that aren't closed
3557 // by the app will leak. Well we try to warning them a lot
3558 // about leaking windows, because that is a bug, so if they are
3559 // using this recreate facility then they get to live with leaks.
3560 WindowManagerGlobal.getInstance().closeAll(token,
3561 r.activity.getClass().getName(), "Activity");
3564 // Mocked out contexts won't be participating in the normal
3565 // process lifecycle, but if we're running with a proper
3566 // ApplicationContext we need to have it tear down things
3568 Context c = r.activity.getBaseContext();
3569 if (c instanceof ContextImpl) {
3570 ((ContextImpl) c).scheduleFinalCleanup(
3571 r.activity.getClass().getName(), "Activity");
3576 ActivityManagerNative.getDefault().activityDestroyed(token);
3577 } catch (RemoteException ex) {
3578 // If the system process has died, it's game over for everyone.
3583 public final void requestRelaunchActivity(IBinder token,
3584 List<ResultInfo> pendingResults, List<Intent> pendingNewIntents,
3585 int configChanges, boolean notResumed, Configuration config,
3586 boolean fromServer) {
3587 ActivityClientRecord target = null;
3589 synchronized (mResourcesManager) {
3590 for (int i=0; i<mRelaunchingActivities.size(); i++) {
3591 ActivityClientRecord r = mRelaunchingActivities.get(i);
3592 if (r.token == token) {
3594 if (pendingResults != null) {
3595 if (r.pendingResults != null) {
3596 r.pendingResults.addAll(pendingResults);
3598 r.pendingResults = pendingResults;
3601 if (pendingNewIntents != null) {
3602 if (r.pendingIntents != null) {
3603 r.pendingIntents.addAll(pendingNewIntents);
3605 r.pendingIntents = pendingNewIntents;
3612 if (target == null) {
3613 target = new ActivityClientRecord();
3614 target.token = token;
3615 target.pendingResults = pendingResults;
3616 target.pendingIntents = pendingNewIntents;
3618 ActivityClientRecord existing = mActivities.get(token);
3619 if (existing != null) {
3620 target.startsNotResumed = existing.paused;
3622 target.onlyLocalRequest = true;
3624 mRelaunchingActivities.add(target);
3625 sendMessage(H.RELAUNCH_ACTIVITY, target);
3629 target.startsNotResumed = notResumed;
3630 target.onlyLocalRequest = false;
3632 if (config != null) {
3633 target.createdConfig = config;
3635 target.pendingConfigChanges |= configChanges;
3639 private void handleRelaunchActivity(ActivityClientRecord tmp) {
3640 // If we are getting ready to gc after going to the background, well
3641 // we are back active so skip it.
3642 unscheduleGcIdler();
3644 Configuration changedConfig = null;
3645 int configChanges = 0;
3647 // First: make sure we have the most recent configuration and most
3648 // recent version of the activity, or skip it if some previous call
3649 // had taken a more recent version.
3650 synchronized (mResourcesManager) {
3651 int N = mRelaunchingActivities.size();
3652 IBinder token = tmp.token;
3654 for (int i=0; i<N; i++) {
3655 ActivityClientRecord r = mRelaunchingActivities.get(i);
3656 if (r.token == token) {
3658 configChanges |= tmp.pendingConfigChanges;
3659 mRelaunchingActivities.remove(i);
3666 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Abort, activity not relaunching!");
3670 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Relaunching activity "
3671 + tmp.token + " with configChanges=0x"
3672 + Integer.toHexString(configChanges));
3674 if (mPendingConfiguration != null) {
3675 changedConfig = mPendingConfiguration;
3676 mPendingConfiguration = null;
3680 if (tmp.createdConfig != null) {
3681 // If the activity manager is passing us its current config,
3682 // assume that is really what we want regardless of what we
3683 // may have pending.
3684 if (mConfiguration == null
3685 || (tmp.createdConfig.isOtherSeqNewer(mConfiguration)
3686 && mConfiguration.diff(tmp.createdConfig) != 0)) {
3687 if (changedConfig == null
3688 || tmp.createdConfig.isOtherSeqNewer(changedConfig)) {
3689 changedConfig = tmp.createdConfig;
3694 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Relaunching activity "
3695 + tmp.token + ": changedConfig=" + changedConfig);
3697 // If there was a pending configuration change, execute it first.
3698 if (changedConfig != null) {
3699 mCurDefaultDisplayDpi = changedConfig.densityDpi;
3700 updateDefaultDensity();
3701 handleConfigurationChanged(changedConfig, null);
3704 ActivityClientRecord r = mActivities.get(tmp.token);
3705 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handling relaunch of " + r);
3710 r.activity.mConfigChangeFlags |= configChanges;
3711 r.onlyLocalRequest = tmp.onlyLocalRequest;
3712 Intent currentIntent = r.activity.mIntent;
3714 r.activity.mChangingConfigurations = true;
3716 // Need to ensure state is saved.
3718 performPauseActivity(r.token, false, r.isPreHoneycomb());
3720 if (r.state == null && !r.stopped && !r.isPreHoneycomb()) {
3721 r.state = new Bundle();
3722 r.state.setAllowFds(false);
3723 mInstrumentation.callActivityOnSaveInstanceState(r.activity, r.state);
3726 handleDestroyActivity(r.token, false, configChanges, true);
3730 r.hideForNow = false;
3732 // Merge any pending results and pending intents; don't just replace them
3733 if (tmp.pendingResults != null) {
3734 if (r.pendingResults == null) {
3735 r.pendingResults = tmp.pendingResults;
3737 r.pendingResults.addAll(tmp.pendingResults);
3740 if (tmp.pendingIntents != null) {
3741 if (r.pendingIntents == null) {
3742 r.pendingIntents = tmp.pendingIntents;
3744 r.pendingIntents.addAll(tmp.pendingIntents);
3747 r.startsNotResumed = tmp.startsNotResumed;
3749 handleLaunchActivity(r, currentIntent);
3752 private void handleRequestThumbnail(IBinder token) {
3753 ActivityClientRecord r = mActivities.get(token);
3754 Bitmap thumbnail = createThumbnailBitmap(r);
3755 CharSequence description = null;
3757 description = r.activity.onCreateDescription();
3758 } catch (Exception e) {
3759 if (!mInstrumentation.onException(r.activity, e)) {
3760 throw new RuntimeException(
3761 "Unable to create description of activity "
3762 + r.intent.getComponent().toShortString()
3763 + ": " + e.toString(), e);
3766 //System.out.println("Reporting top thumbnail " + thumbnail);
3768 ActivityManagerNative.getDefault().reportThumbnail(
3769 token, thumbnail, description);
3770 } catch (RemoteException ex) {
3774 ArrayList<ComponentCallbacks2> collectComponentCallbacks(
3775 boolean allActivities, Configuration newConfig) {
3776 ArrayList<ComponentCallbacks2> callbacks
3777 = new ArrayList<ComponentCallbacks2>();
3779 synchronized (mResourcesManager) {
3780 final int NAPP = mAllApplications.size();
3781 for (int i=0; i<NAPP; i++) {
3782 callbacks.add(mAllApplications.get(i));
3784 final int NACT = mActivities.size();
3785 for (int i=0; i<NACT; i++) {
3786 ActivityClientRecord ar = mActivities.valueAt(i);
3787 Activity a = ar.activity;
3789 Configuration thisConfig = applyConfigCompatMainThread(
3790 mCurDefaultDisplayDpi, newConfig,
3791 ar.packageInfo.getCompatibilityInfo());
3792 if (!ar.activity.mFinished && (allActivities || !ar.paused)) {
3793 // If the activity is currently resumed, its configuration
3794 // needs to change right now.
3796 } else if (thisConfig != null) {
3797 // Otherwise, we will tell it about the change
3798 // the next time it is resumed or shown. Note that
3799 // the activity manager may, before then, decide the
3800 // activity needs to be destroyed to handle its new
3802 if (DEBUG_CONFIGURATION) {
3803 Slog.v(TAG, "Setting activity "
3804 + ar.activityInfo.name + " newConfig=" + thisConfig);
3806 ar.newConfig = thisConfig;
3810 final int NSVC = mServices.size();
3811 for (int i=0; i<NSVC; i++) {
3812 callbacks.add(mServices.valueAt(i));
3815 synchronized (mProviderMap) {
3816 final int NPRV = mLocalProviders.size();
3817 for (int i=0; i<NPRV; i++) {
3818 callbacks.add(mLocalProviders.valueAt(i).mLocalProvider);
3825 private static void performConfigurationChanged(ComponentCallbacks2 cb, Configuration config) {
3826 // Only for Activity objects, check that they actually call up to their
3827 // superclass implementation. ComponentCallbacks2 is an interface, so
3828 // we check the runtime type and act accordingly.
3829 Activity activity = (cb instanceof Activity) ? (Activity) cb : null;
3830 if (activity != null) {
3831 activity.mCalled = false;
3834 boolean shouldChangeConfig = false;
3835 if ((activity == null) || (activity.mCurrentConfig == null)) {
3836 shouldChangeConfig = true;
3839 // If the new config is the same as the config this Activity
3840 // is already running with then don't bother calling
3841 // onConfigurationChanged
3842 int diff = activity.mCurrentConfig.diff(config);
3844 // If this activity doesn't handle any of the config changes
3845 // then don't bother calling onConfigurationChanged as we're
3846 // going to destroy it.
3847 if ((~activity.mActivityInfo.getRealConfigChanged() & diff) == 0) {
3848 shouldChangeConfig = true;
3853 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Config callback " + cb
3854 + ": shouldChangeConfig=" + shouldChangeConfig);
3855 if (shouldChangeConfig) {
3856 cb.onConfigurationChanged(config);
3858 if (activity != null) {
3859 if (!activity.mCalled) {
3860 throw new SuperNotCalledException(
3861 "Activity " + activity.getLocalClassName() +
3862 " did not call through to super.onConfigurationChanged()");
3864 activity.mConfigChangeFlags = 0;
3865 activity.mCurrentConfig = new Configuration(config);
3870 public final void applyConfigurationToResources(Configuration config) {
3871 synchronized (mResourcesManager) {
3872 mResourcesManager.applyConfigurationToResourcesLocked(config, null);
3876 final Configuration applyCompatConfiguration(int displayDensity) {
3877 Configuration config = mConfiguration;
3878 if (mCompatConfiguration == null) {
3879 mCompatConfiguration = new Configuration();
3881 mCompatConfiguration.setTo(mConfiguration);
3882 if (mResourcesManager.applyCompatConfiguration(displayDensity, mCompatConfiguration)) {
3883 config = mCompatConfiguration;
3888 final void handleConfigurationChanged(Configuration config, CompatibilityInfo compat) {
3892 synchronized (mResourcesManager) {
3893 if (mPendingConfiguration != null) {
3894 if (!mPendingConfiguration.isOtherSeqNewer(config)) {
3895 config = mPendingConfiguration;
3896 mCurDefaultDisplayDpi = config.densityDpi;
3897 updateDefaultDensity();
3899 mPendingConfiguration = null;
3902 if (config == null) {
3906 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handle configuration changed: "
3909 mResourcesManager.applyConfigurationToResourcesLocked(config, compat);
3911 if (mConfiguration == null) {
3912 mConfiguration = new Configuration();
3914 if (!mConfiguration.isOtherSeqNewer(config) && compat == null) {
3917 configDiff = mConfiguration.diff(config);
3918 mConfiguration.updateFrom(config);
3919 config = applyCompatConfiguration(mCurDefaultDisplayDpi);
3922 ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(false, config);
3924 // Cleanup hardware accelerated stuff
3925 WindowManagerGlobal.getInstance().trimLocalMemory();
3927 freeTextLayoutCachesIfNeeded(configDiff);
3929 if (callbacks != null) {
3930 final int N = callbacks.size();
3931 for (int i=0; i<N; i++) {
3932 performConfigurationChanged(callbacks.get(i), config);
3937 static void freeTextLayoutCachesIfNeeded(int configDiff) {
3938 if (configDiff != 0) {
3939 // Ask text layout engine to free its caches if there is a locale change
3940 boolean hasLocaleConfigChange = ((configDiff & ActivityInfo.CONFIG_LOCALE) != 0);
3941 if (hasLocaleConfigChange) {
3942 Canvas.freeTextLayoutCaches();
3943 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Cleared TextLayout Caches");
3948 final void handleActivityConfigurationChanged(IBinder token) {
3949 ActivityClientRecord r = mActivities.get(token);
3950 if (r == null || r.activity == null) {
3954 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handle activity config changed: "
3955 + r.activityInfo.name);
3957 performConfigurationChanged(r.activity, mCompatConfiguration);
3959 freeTextLayoutCachesIfNeeded(r.activity.mCurrentConfig.diff(mCompatConfiguration));
3962 final void handleProfilerControl(boolean start, ProfilerControlData pcd, int profileType) {
3965 switch (profileType) {
3967 mProfiler.setProfiler(pcd.path, pcd.fd);
3968 mProfiler.autoStopProfiler = false;
3969 mProfiler.startProfiling();
3972 } catch (RuntimeException e) {
3973 Slog.w(TAG, "Profiling failed on path " + pcd.path
3974 + " -- can the process access this path?");
3978 } catch (IOException e) {
3979 Slog.w(TAG, "Failure closing profile fd", e);
3983 switch (profileType) {
3985 mProfiler.stopProfiling();
3991 static final void handleDumpHeap(boolean managed, DumpHeapData dhd) {
3994 Debug.dumpHprofData(dhd.path, dhd.fd.getFileDescriptor());
3995 } catch (IOException e) {
3996 Slog.w(TAG, "Managed heap dump failed on path " + dhd.path
3997 + " -- can the process access this path?");
4001 } catch (IOException e) {
4002 Slog.w(TAG, "Failure closing profile fd", e);
4006 Debug.dumpNativeHeap(dhd.fd.getFileDescriptor());
4010 final void handleDispatchPackageBroadcast(int cmd, String[] packages) {
4011 boolean hasPkgInfo = false;
4012 if (packages != null) {
4013 for (int i=packages.length-1; i>=0; i--) {
4014 //Slog.i(TAG, "Cleaning old package: " + packages[i]);
4016 WeakReference<LoadedApk> ref;
4017 ref = mPackages.get(packages[i]);
4018 if (ref != null && ref.get() != null) {
4021 ref = mResourcePackages.get(packages[i]);
4022 if (ref != null && ref.get() != null) {
4027 mPackages.remove(packages[i]);
4028 mResourcePackages.remove(packages[i]);
4031 ApplicationPackageManager.handlePackageBroadcast(cmd, packages,
4035 final void handleLowMemory() {
4036 ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(true, null);
4038 final int N = callbacks.size();
4039 for (int i=0; i<N; i++) {
4040 callbacks.get(i).onLowMemory();
4043 // Ask SQLite to free up as much memory as it can, mostly from its page caches.
4044 if (Process.myUid() != Process.SYSTEM_UID) {
4045 int sqliteReleased = SQLiteDatabase.releaseMemory();
4046 EventLog.writeEvent(SQLITE_MEM_RELEASED_EVENT_LOG_TAG, sqliteReleased);
4049 // Ask graphics to free up as much as possible (font/image caches)
4050 Canvas.freeCaches();
4052 // Ask text layout engine to free also as much as possible
4053 Canvas.freeTextLayoutCaches();
4055 BinderInternal.forceGc("mem");
4058 final void handleTrimMemory(int level) {
4059 if (DEBUG_MEMORY_TRIM) Slog.v(TAG, "Trimming memory to level: " + level);
4061 final WindowManagerGlobal windowManager = WindowManagerGlobal.getInstance();
4062 windowManager.startTrimMemory(level);
4064 ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(true, null);
4066 final int N = callbacks.size();
4067 for (int i = 0; i < N; i++) {
4068 callbacks.get(i).onTrimMemory(level);
4071 windowManager.endTrimMemory();
4074 private void setupGraphicsSupport(LoadedApk info, File cacheDir) {
4075 if (Process.isIsolated()) {
4076 // Isolated processes aren't going to do UI.
4080 int uid = Process.myUid();
4081 String[] packages = getPackageManager().getPackagesForUid(uid);
4083 // If there are several packages in this application we won't
4084 // initialize the graphics disk caches
4085 if (packages != null && packages.length == 1) {
4086 HardwareRenderer.setupDiskCache(cacheDir);
4087 RenderScript.setupDiskCache(cacheDir);
4089 } catch (RemoteException e) {
4094 private void updateDefaultDensity() {
4095 if (mCurDefaultDisplayDpi != Configuration.DENSITY_DPI_UNDEFINED
4096 && mCurDefaultDisplayDpi != DisplayMetrics.DENSITY_DEVICE
4097 && !mDensityCompatMode) {
4098 Slog.i(TAG, "Switching default density from "
4099 + DisplayMetrics.DENSITY_DEVICE + " to "
4100 + mCurDefaultDisplayDpi);
4101 DisplayMetrics.DENSITY_DEVICE = mCurDefaultDisplayDpi;
4102 Bitmap.setDefaultDensity(DisplayMetrics.DENSITY_DEFAULT);
4106 private void handleBindApplication(AppBindData data) {
4107 mBoundApplication = data;
4108 mConfiguration = new Configuration(data.config);
4109 mCompatConfiguration = new Configuration(data.config);
4111 mProfiler = new Profiler();
4112 mProfiler.profileFile = data.initProfileFile;
4113 mProfiler.profileFd = data.initProfileFd;
4114 mProfiler.autoStopProfiler = data.initAutoStopProfiler;
4116 // send up app name; do this *before* waiting for debugger
4117 Process.setArgV0(data.processName);
4118 android.ddm.DdmHandleAppName.setAppName(data.processName,
4119 UserHandle.myUserId());
4121 if (data.persistent) {
4122 // Persistent processes on low-memory devices do not get to
4123 // use hardware accelerated drawing, since this can add too much
4124 // overhead to the process.
4125 if (!ActivityManager.isHighEndGfx()) {
4126 HardwareRenderer.disable(false);
4130 if (mProfiler.profileFd != null) {
4131 mProfiler.startProfiling();
4134 // If the app is Honeycomb MR1 or earlier, switch its AsyncTask
4135 // implementation to use the pool executor. Normally, we use the
4136 // serialized executor as the default. This has to happen in the
4137 // main thread so the main looper is set right.
4138 if (data.appInfo.targetSdkVersion <= android.os.Build.VERSION_CODES.HONEYCOMB_MR1) {
4139 AsyncTask.setDefaultExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
4143 * Before spawning a new process, reset the time zone to be the system time zone.
4144 * This needs to be done because the system time zone could have changed after the
4145 * the spawning of this process. Without doing this this process would have the incorrect
4148 TimeZone.setDefault(null);
4151 * Initialize the default locale in this process for the reasons we set the time zone.
4153 Locale.setDefault(data.config.locale);
4156 * Update the system configuration since its preloaded and might not
4157 * reflect configuration changes. The configuration object passed
4158 * in AppBindData can be safely assumed to be up to date
4160 mResourcesManager.applyConfigurationToResourcesLocked(data.config, data.compatInfo);
4161 mCurDefaultDisplayDpi = data.config.densityDpi;
4162 applyCompatConfiguration(mCurDefaultDisplayDpi);
4164 data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
4167 * Switch this process to density compatibility mode if needed.
4169 if ((data.appInfo.flags&ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES)
4171 mDensityCompatMode = true;
4172 Bitmap.setDefaultDensity(DisplayMetrics.DENSITY_DEFAULT);
4174 updateDefaultDensity();
4176 final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);
4177 if (!Process.isIsolated()) {
4178 final File cacheDir = appContext.getCacheDir();
4180 if (cacheDir != null) {
4181 // Provide a usable directory for temporary files
4182 System.setProperty("java.io.tmpdir", cacheDir.getAbsolutePath());
4184 setupGraphicsSupport(data.info, cacheDir);
4186 Log.e(TAG, "Unable to setupGraphicsSupport due to missing cache directory");
4190 * For system applications on userdebug/eng builds, log stack
4191 * traces of disk and network access to dropbox for analysis.
4193 if ((data.appInfo.flags &
4194 (ApplicationInfo.FLAG_SYSTEM |
4195 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0) {
4196 StrictMode.conditionallyEnableDebugLogging();
4200 * For apps targetting SDK Honeycomb or later, we don't allow
4201 * network usage on the main event loop / UI thread.
4203 * Note to those grepping: this is what ultimately throws
4204 * NetworkOnMainThreadException ...
4206 if (data.appInfo.targetSdkVersion > 9) {
4207 StrictMode.enableDeathOnNetwork();
4210 if (data.debugMode != IApplicationThread.DEBUG_OFF) {
4211 // XXX should have option to change the port.
4212 Debug.changeDebugPort(8100);
4213 if (data.debugMode == IApplicationThread.DEBUG_WAIT) {
4214 Slog.w(TAG, "Application " + data.info.getPackageName()
4215 + " is waiting for the debugger on port 8100...");
4217 IActivityManager mgr = ActivityManagerNative.getDefault();
4219 mgr.showWaitingForDebugger(mAppThread, true);
4220 } catch (RemoteException ex) {
4223 Debug.waitForDebugger();
4226 mgr.showWaitingForDebugger(mAppThread, false);
4227 } catch (RemoteException ex) {
4231 Slog.w(TAG, "Application " + data.info.getPackageName()
4232 + " can be debugged on port 8100...");
4236 // Enable OpenGL tracing if required
4237 if (data.enableOpenGlTrace) {
4238 GLUtils.setTracingLevel(1);
4241 // Allow application-generated systrace messages if we're debuggable.
4242 boolean appTracingAllowed = (data.appInfo.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0;
4243 Trace.setAppTracingAllowed(appTracingAllowed);
4246 * Initialize the default http proxy in this process for the reasons we set the time zone.
4248 IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE);
4250 // In pre-boot mode (doing initial launch to collect password), not
4251 // all system is up. This includes the connectivity service, so don't
4252 // crash if we can't get it.
4253 IConnectivityManager service = IConnectivityManager.Stub.asInterface(b);
4255 ProxyProperties proxyProperties = service.getProxy();
4256 Proxy.setHttpProxySystemProperty(proxyProperties);
4257 } catch (RemoteException e) {}
4260 if (data.instrumentationName != null) {
4261 InstrumentationInfo ii = null;
4263 ii = appContext.getPackageManager().
4264 getInstrumentationInfo(data.instrumentationName, 0);
4265 } catch (PackageManager.NameNotFoundException e) {
4268 throw new RuntimeException(
4269 "Unable to find instrumentation info for: "
4270 + data.instrumentationName);
4273 mInstrumentationAppDir = ii.sourceDir;
4274 mInstrumentationAppLibraryDir = ii.nativeLibraryDir;
4275 mInstrumentationAppPackage = ii.packageName;
4276 mInstrumentedAppDir = data.info.getAppDir();
4277 mInstrumentedAppLibraryDir = data.info.getLibDir();
4279 ApplicationInfo instrApp = new ApplicationInfo();
4280 instrApp.packageName = ii.packageName;
4281 instrApp.sourceDir = ii.sourceDir;
4282 instrApp.publicSourceDir = ii.publicSourceDir;
4283 instrApp.dataDir = ii.dataDir;
4284 instrApp.nativeLibraryDir = ii.nativeLibraryDir;
4285 LoadedApk pi = getPackageInfo(instrApp, data.compatInfo,
4286 appContext.getClassLoader(), false, true);
4287 ContextImpl instrContext = ContextImpl.createAppContext(this, pi);
4290 java.lang.ClassLoader cl = instrContext.getClassLoader();
4291 mInstrumentation = (Instrumentation)
4292 cl.loadClass(data.instrumentationName.getClassName()).newInstance();
4293 } catch (Exception e) {
4294 throw new RuntimeException(
4295 "Unable to instantiate instrumentation "
4296 + data.instrumentationName + ": " + e.toString(), e);
4299 mInstrumentation.init(this, instrContext, appContext,
4300 new ComponentName(ii.packageName, ii.name), data.instrumentationWatcher,
4301 data.instrumentationUiAutomationConnection);
4303 if (mProfiler.profileFile != null && !ii.handleProfiling
4304 && mProfiler.profileFd == null) {
4305 mProfiler.handlingProfiling = true;
4306 File file = new File(mProfiler.profileFile);
4307 file.getParentFile().mkdirs();
4308 Debug.startMethodTracing(file.toString(), 8 * 1024 * 1024);
4312 mInstrumentation = new Instrumentation();
4315 if ((data.appInfo.flags&ApplicationInfo.FLAG_LARGE_HEAP) != 0) {
4316 dalvik.system.VMRuntime.getRuntime().clearGrowthLimit();
4319 // Allow disk access during application and provider setup. This could
4320 // block processing ordered broadcasts, but later processing would
4321 // probably end up doing the same disk access.
4322 final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskWrites();
4324 // If the app is being launched for full backup or restore, bring it up in
4325 // a restricted environment with the base application class.
4326 Application app = data.info.makeApplication(data.restrictedBackupMode, null);
4327 mInitialApplication = app;
4329 // don't bring up providers in restricted mode; they may depend on the
4330 // app's custom Application class
4331 if (!data.restrictedBackupMode) {
4332 List<ProviderInfo> providers = data.providers;
4333 if (providers != null) {
4334 installContentProviders(app, providers);
4335 // For process that contains content providers, we want to
4336 // ensure that the JIT is enabled "at some point".
4337 mH.sendEmptyMessageDelayed(H.ENABLE_JIT, 10*1000);
4341 // Do this after providers, since instrumentation tests generally start their
4342 // test thread at this point, and we don't want that racing.
4344 mInstrumentation.onCreate(data.instrumentationArgs);
4346 catch (Exception e) {
4347 throw new RuntimeException(
4348 "Exception thrown in onCreate() of "
4349 + data.instrumentationName + ": " + e.toString(), e);
4353 mInstrumentation.callApplicationOnCreate(app);
4354 } catch (Exception e) {
4355 if (!mInstrumentation.onException(app, e)) {
4356 throw new RuntimeException(
4357 "Unable to create application " + app.getClass().getName()
4358 + ": " + e.toString(), e);
4362 StrictMode.setThreadPolicy(savedPolicy);
4366 /*package*/ final void finishInstrumentation(int resultCode, Bundle results) {
4367 IActivityManager am = ActivityManagerNative.getDefault();
4368 if (mProfiler.profileFile != null && mProfiler.handlingProfiling
4369 && mProfiler.profileFd == null) {
4370 Debug.stopMethodTracing();
4372 //Slog.i(TAG, "am: " + ActivityManagerNative.getDefault()
4373 // + ", app thr: " + mAppThread);
4375 am.finishInstrumentation(mAppThread, resultCode, results);
4376 } catch (RemoteException ex) {
4380 private void installContentProviders(
4381 Context context, List<ProviderInfo> providers) {
4382 final ArrayList<IActivityManager.ContentProviderHolder> results =
4383 new ArrayList<IActivityManager.ContentProviderHolder>();
4385 for (ProviderInfo cpi : providers) {
4386 if (DEBUG_PROVIDER) {
4387 StringBuilder buf = new StringBuilder(128);
4389 buf.append(cpi.authority);
4391 buf.append(cpi.name);
4392 Log.i(TAG, buf.toString());
4394 IActivityManager.ContentProviderHolder cph = installProvider(context, null, cpi,
4395 false /*noisy*/, true /*noReleaseNeeded*/, true /*stable*/);
4397 cph.noReleaseNeeded = true;
4403 ActivityManagerNative.getDefault().publishContentProviders(
4404 getApplicationThread(), results);
4405 } catch (RemoteException ex) {
4409 public final IContentProvider acquireProvider(
4410 Context c, String auth, int userId, boolean stable) {
4411 final IContentProvider provider = acquireExistingProvider(c, auth, userId, stable);
4412 if (provider != null) {
4416 // There is a possible race here. Another thread may try to acquire
4417 // the same provider at the same time. When this happens, we want to ensure
4418 // that the first one wins.
4419 // Note that we cannot hold the lock while acquiring and installing the
4420 // provider since it might take a long time to run and it could also potentially
4421 // be re-entrant in the case where the provider is in the same process.
4422 IActivityManager.ContentProviderHolder holder = null;
4424 holder = ActivityManagerNative.getDefault().getContentProvider(
4425 getApplicationThread(), auth, userId, stable);
4426 } catch (RemoteException ex) {
4428 if (holder == null) {
4429 Slog.e(TAG, "Failed to find provider info for " + auth);
4433 // Install provider will increment the reference count for us, and break
4434 // any ties in the race.
4435 holder = installProvider(c, holder, holder.info,
4436 true /*noisy*/, holder.noReleaseNeeded, stable);
4437 return holder.provider;
4440 private final void incProviderRefLocked(ProviderRefCount prc, boolean stable) {
4442 prc.stableCount += 1;
4443 if (prc.stableCount == 1) {
4444 // We are acquiring a new stable reference on the provider.
4446 if (prc.removePending) {
4447 // We have a pending remove operation, which is holding the
4448 // last unstable reference. At this point we are converting
4449 // that unstable reference to our new stable reference.
4451 // Cancel the removal of the provider.
4452 if (DEBUG_PROVIDER) {
4453 Slog.v(TAG, "incProviderRef: stable "
4454 + "snatched provider from the jaws of death");
4456 prc.removePending = false;
4457 // There is a race! It fails to remove the message, which
4458 // will be handled in completeRemoveProvider().
4459 mH.removeMessages(H.REMOVE_PROVIDER, prc);
4464 if (DEBUG_PROVIDER) {
4465 Slog.v(TAG, "incProviderRef Now stable - "
4466 + prc.holder.info.name + ": unstableDelta="
4469 ActivityManagerNative.getDefault().refContentProvider(
4470 prc.holder.connection, 1, unstableDelta);
4471 } catch (RemoteException e) {
4472 //do nothing content provider object is dead any way
4476 prc.unstableCount += 1;
4477 if (prc.unstableCount == 1) {
4478 // We are acquiring a new unstable reference on the provider.
4479 if (prc.removePending) {
4480 // Oh look, we actually have a remove pending for the
4481 // provider, which is still holding the last unstable
4482 // reference. We just need to cancel that to take new
4483 // ownership of the reference.
4484 if (DEBUG_PROVIDER) {
4485 Slog.v(TAG, "incProviderRef: unstable "
4486 + "snatched provider from the jaws of death");
4488 prc.removePending = false;
4489 mH.removeMessages(H.REMOVE_PROVIDER, prc);
4491 // First unstable ref, increment our count in the
4492 // activity manager.
4494 if (DEBUG_PROVIDER) {
4495 Slog.v(TAG, "incProviderRef: Now unstable - "
4496 + prc.holder.info.name);
4498 ActivityManagerNative.getDefault().refContentProvider(
4499 prc.holder.connection, 0, 1);
4500 } catch (RemoteException e) {
4501 //do nothing content provider object is dead any way
4508 public final IContentProvider acquireExistingProvider(
4509 Context c, String auth, int userId, boolean stable) {
4510 synchronized (mProviderMap) {
4511 final ProviderKey key = new ProviderKey(auth, userId);
4512 final ProviderClientRecord pr = mProviderMap.get(key);
4517 IContentProvider provider = pr.mProvider;
4518 IBinder jBinder = provider.asBinder();
4519 if (!jBinder.isBinderAlive()) {
4520 // The hosting process of the provider has died; we can't
4522 Log.i(TAG, "Acquiring provider " + auth + " for user " + userId
4523 + ": existing object's process dead");
4524 handleUnstableProviderDiedLocked(jBinder, true);
4528 // Only increment the ref count if we have one. If we don't then the
4529 // provider is not reference counted and never needs to be released.
4530 ProviderRefCount prc = mProviderRefCountMap.get(jBinder);
4532 incProviderRefLocked(prc, stable);
4538 public final boolean releaseProvider(IContentProvider provider, boolean stable) {
4539 if (provider == null) {
4543 IBinder jBinder = provider.asBinder();
4544 synchronized (mProviderMap) {
4545 ProviderRefCount prc = mProviderRefCountMap.get(jBinder);
4547 // The provider has no ref count, no release is needed.
4551 boolean lastRef = false;
4553 if (prc.stableCount == 0) {
4554 if (DEBUG_PROVIDER) Slog.v(TAG,
4555 "releaseProvider: stable ref count already 0, how?");
4558 prc.stableCount -= 1;
4559 if (prc.stableCount == 0) {
4560 // What we do at this point depends on whether there are
4561 // any unstable refs left: if there are, we just tell the
4562 // activity manager to decrement its stable count; if there
4563 // aren't, we need to enqueue this provider to be removed,
4564 // and convert to holding a single unstable ref while
4566 lastRef = prc.unstableCount == 0;
4568 if (DEBUG_PROVIDER) {
4569 Slog.v(TAG, "releaseProvider: No longer stable w/lastRef="
4570 + lastRef + " - " + prc.holder.info.name);
4572 ActivityManagerNative.getDefault().refContentProvider(
4573 prc.holder.connection, -1, lastRef ? 1 : 0);
4574 } catch (RemoteException e) {
4575 //do nothing content provider object is dead any way
4579 if (prc.unstableCount == 0) {
4580 if (DEBUG_PROVIDER) Slog.v(TAG,
4581 "releaseProvider: unstable ref count already 0, how?");
4584 prc.unstableCount -= 1;
4585 if (prc.unstableCount == 0) {
4586 // If this is the last reference, we need to enqueue
4587 // this provider to be removed instead of telling the
4588 // activity manager to remove it at this point.
4589 lastRef = prc.stableCount == 0;
4592 if (DEBUG_PROVIDER) {
4593 Slog.v(TAG, "releaseProvider: No longer unstable - "
4594 + prc.holder.info.name);
4596 ActivityManagerNative.getDefault().refContentProvider(
4597 prc.holder.connection, 0, -1);
4598 } catch (RemoteException e) {
4599 //do nothing content provider object is dead any way
4606 if (!prc.removePending) {
4607 // Schedule the actual remove asynchronously, since we don't know the context
4608 // this will be called in.
4609 // TODO: it would be nice to post a delayed message, so
4610 // if we come back and need the same provider quickly
4611 // we will still have it available.
4612 if (DEBUG_PROVIDER) {
4613 Slog.v(TAG, "releaseProvider: Enqueueing pending removal - "
4614 + prc.holder.info.name);
4616 prc.removePending = true;
4617 Message msg = mH.obtainMessage(H.REMOVE_PROVIDER, prc);
4618 mH.sendMessage(msg);
4620 Slog.w(TAG, "Duplicate remove pending of provider " + prc.holder.info.name);
4627 final void completeRemoveProvider(ProviderRefCount prc) {
4628 synchronized (mProviderMap) {
4629 if (!prc.removePending) {
4630 // There was a race! Some other client managed to acquire
4631 // the provider before the removal was completed.
4632 // Abort the removal. We will do it later.
4633 if (DEBUG_PROVIDER) Slog.v(TAG, "completeRemoveProvider: lost the race, "
4634 + "provider still in use");
4638 // More complicated race!! Some client managed to acquire the
4639 // provider and release it before the removal was completed.
4640 // Continue the removal, and abort the next remove message.
4641 prc.removePending = false;
4643 final IBinder jBinder = prc.holder.provider.asBinder();
4644 ProviderRefCount existingPrc = mProviderRefCountMap.get(jBinder);
4645 if (existingPrc == prc) {
4646 mProviderRefCountMap.remove(jBinder);
4649 for (int i=mProviderMap.size()-1; i>=0; i--) {
4650 ProviderClientRecord pr = mProviderMap.valueAt(i);
4651 IBinder myBinder = pr.mProvider.asBinder();
4652 if (myBinder == jBinder) {
4653 mProviderMap.removeAt(i);
4659 if (DEBUG_PROVIDER) {
4660 Slog.v(TAG, "removeProvider: Invoking ActivityManagerNative."
4661 + "removeContentProvider(" + prc.holder.info.name + ")");
4663 ActivityManagerNative.getDefault().removeContentProvider(
4664 prc.holder.connection, false);
4665 } catch (RemoteException e) {
4666 //do nothing content provider object is dead any way
4670 final void handleUnstableProviderDied(IBinder provider, boolean fromClient) {
4671 synchronized (mProviderMap) {
4672 handleUnstableProviderDiedLocked(provider, fromClient);
4676 final void handleUnstableProviderDiedLocked(IBinder provider, boolean fromClient) {
4677 ProviderRefCount prc = mProviderRefCountMap.get(provider);
4679 if (DEBUG_PROVIDER) Slog.v(TAG, "Cleaning up dead provider "
4680 + provider + " " + prc.holder.info.name);
4681 mProviderRefCountMap.remove(provider);
4682 for (int i=mProviderMap.size()-1; i>=0; i--) {
4683 ProviderClientRecord pr = mProviderMap.valueAt(i);
4684 if (pr != null && pr.mProvider.asBinder() == provider) {
4685 Slog.i(TAG, "Removing dead content provider:" + pr.mProvider.toString());
4686 mProviderMap.removeAt(i);
4691 // We found out about this due to execution in our client
4692 // code. Tell the activity manager about it now, to ensure
4693 // that the next time we go to do anything with the provider
4694 // it knows it is dead (so we don't race with its death
4697 ActivityManagerNative.getDefault().unstableProviderDied(
4698 prc.holder.connection);
4699 } catch (RemoteException e) {
4700 //do nothing content provider object is dead any way
4706 final void appNotRespondingViaProvider(IBinder provider) {
4707 synchronized (mProviderMap) {
4708 ProviderRefCount prc = mProviderRefCountMap.get(provider);
4711 ActivityManagerNative.getDefault()
4712 .appNotRespondingViaProvider(prc.holder.connection);
4713 } catch (RemoteException e) {
4719 private ProviderClientRecord installProviderAuthoritiesLocked(IContentProvider provider,
4720 ContentProvider localProvider, IActivityManager.ContentProviderHolder holder) {
4721 final String auths[] = PATTERN_SEMICOLON.split(holder.info.authority);
4722 final int userId = UserHandle.getUserId(holder.info.applicationInfo.uid);
4724 final ProviderClientRecord pcr = new ProviderClientRecord(
4725 auths, provider, localProvider, holder);
4726 for (String auth : auths) {
4727 final ProviderKey key = new ProviderKey(auth, userId);
4728 final ProviderClientRecord existing = mProviderMap.get(key);
4729 if (existing != null) {
4730 Slog.w(TAG, "Content provider " + pcr.mHolder.info.name
4731 + " already published as " + auth);
4733 mProviderMap.put(key, pcr);
4740 * Installs the provider.
4742 * Providers that are local to the process or that come from the system server
4743 * may be installed permanently which is indicated by setting noReleaseNeeded to true.
4744 * Other remote providers are reference counted. The initial reference count
4745 * for all reference counted providers is one. Providers that are not reference
4746 * counted do not have a reference count (at all).
4748 * This method detects when a provider has already been installed. When this happens,
4749 * it increments the reference count of the existing provider (if appropriate)
4750 * and returns the existing provider. This can happen due to concurrent
4751 * attempts to acquire the same provider.
4753 private IActivityManager.ContentProviderHolder installProvider(Context context,
4754 IActivityManager.ContentProviderHolder holder, ProviderInfo info,
4755 boolean noisy, boolean noReleaseNeeded, boolean stable) {
4756 ContentProvider localProvider = null;
4757 IContentProvider provider;
4758 if (holder == null || holder.provider == null) {
4759 if (DEBUG_PROVIDER || noisy) {
4760 Slog.d(TAG, "Loading provider " + info.authority + ": "
4764 ApplicationInfo ai = info.applicationInfo;
4765 if (context.getPackageName().equals(ai.packageName)) {
4767 } else if (mInitialApplication != null &&
4768 mInitialApplication.getPackageName().equals(ai.packageName)) {
4769 c = mInitialApplication;
4772 c = context.createPackageContext(ai.packageName,
4773 Context.CONTEXT_INCLUDE_CODE);
4774 } catch (PackageManager.NameNotFoundException e) {
4779 Slog.w(TAG, "Unable to get context for package " +
4781 " while loading content provider " +
4786 final java.lang.ClassLoader cl = c.getClassLoader();
4787 localProvider = (ContentProvider)cl.
4788 loadClass(info.name).newInstance();
4789 provider = localProvider.getIContentProvider();
4790 if (provider == null) {
4791 Slog.e(TAG, "Failed to instantiate class " +
4792 info.name + " from sourceDir " +
4793 info.applicationInfo.sourceDir);
4796 if (DEBUG_PROVIDER) Slog.v(
4797 TAG, "Instantiating local provider " + info.name);
4798 // XXX Need to create the correct context for this provider.
4799 localProvider.attachInfo(c, info);
4800 } catch (java.lang.Exception e) {
4801 if (!mInstrumentation.onException(null, e)) {
4802 throw new RuntimeException(
4803 "Unable to get provider " + info.name
4804 + ": " + e.toString(), e);
4809 provider = holder.provider;
4810 if (DEBUG_PROVIDER) Slog.v(TAG, "Installing external provider " + info.authority + ": "
4814 IActivityManager.ContentProviderHolder retHolder;
4816 synchronized (mProviderMap) {
4817 if (DEBUG_PROVIDER) Slog.v(TAG, "Checking to add " + provider
4818 + " / " + info.name);
4819 IBinder jBinder = provider.asBinder();
4820 if (localProvider != null) {
4821 ComponentName cname = new ComponentName(info.packageName, info.name);
4822 ProviderClientRecord pr = mLocalProvidersByName.get(cname);
4824 if (DEBUG_PROVIDER) {
4825 Slog.v(TAG, "installProvider: lost the race, "
4826 + "using existing local provider");
4828 provider = pr.mProvider;
4830 holder = new IActivityManager.ContentProviderHolder(info);
4831 holder.provider = provider;
4832 holder.noReleaseNeeded = true;
4833 pr = installProviderAuthoritiesLocked(provider, localProvider, holder);
4834 mLocalProviders.put(jBinder, pr);
4835 mLocalProvidersByName.put(cname, pr);
4837 retHolder = pr.mHolder;
4839 ProviderRefCount prc = mProviderRefCountMap.get(jBinder);
4841 if (DEBUG_PROVIDER) {
4842 Slog.v(TAG, "installProvider: lost the race, updating ref count");
4844 // We need to transfer our new reference to the existing
4845 // ref count, releasing the old one... but only if
4846 // release is needed (that is, it is not running in the
4848 if (!noReleaseNeeded) {
4849 incProviderRefLocked(prc, stable);
4851 ActivityManagerNative.getDefault().removeContentProvider(
4852 holder.connection, stable);
4853 } catch (RemoteException e) {
4854 //do nothing content provider object is dead any way
4858 ProviderClientRecord client = installProviderAuthoritiesLocked(
4859 provider, localProvider, holder);
4860 if (noReleaseNeeded) {
4861 prc = new ProviderRefCount(holder, client, 1000, 1000);
4864 ? new ProviderRefCount(holder, client, 1, 0)
4865 : new ProviderRefCount(holder, client, 0, 1);
4867 mProviderRefCountMap.put(jBinder, prc);
4869 retHolder = prc.holder;
4876 private void attach(boolean system) {
4877 sCurrentActivityThread = this;
4878 mSystemThread = system;
4880 ViewRootImpl.addFirstDrawHandler(new Runnable() {
4886 android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",
4887 UserHandle.myUserId());
4888 RuntimeInit.setApplicationObject(mAppThread.asBinder());
4889 IActivityManager mgr = ActivityManagerNative.getDefault();
4891 mgr.attachApplication(mAppThread);
4892 } catch (RemoteException ex) {
4896 // Don't set application object here -- if the system crashes,
4897 // we can't display an alert, we just want to die die die.
4898 android.ddm.DdmHandleAppName.setAppName("system_process",
4899 UserHandle.myUserId());
4901 mInstrumentation = new Instrumentation();
4902 ContextImpl context = ContextImpl.createAppContext(
4903 this, getSystemContext().mPackageInfo);
4904 Application app = Instrumentation.newApplication(Application.class, context);
4905 mAllApplications.add(app);
4906 mInitialApplication = app;
4908 } catch (Exception e) {
4909 throw new RuntimeException(
4910 "Unable to instantiate Application():" + e.toString(), e);
4914 // add dropbox logging to libcore
4915 DropBox.setReporter(new DropBoxReporter());
4917 ViewRootImpl.addConfigCallback(new ComponentCallbacks2() {
4919 public void onConfigurationChanged(Configuration newConfig) {
4920 synchronized (mResourcesManager) {
4921 // We need to apply this change to the resources
4922 // immediately, because upon returning the view
4923 // hierarchy will be informed about it.
4924 if (mResourcesManager.applyConfigurationToResourcesLocked(newConfig, null)) {
4925 // This actually changed the resources! Tell
4926 // everyone about it.
4927 if (mPendingConfiguration == null ||
4928 mPendingConfiguration.isOtherSeqNewer(newConfig)) {
4929 mPendingConfiguration = newConfig;
4931 sendMessage(H.CONFIGURATION_CHANGED, newConfig);
4937 public void onLowMemory() {
4940 public void onTrimMemory(int level) {
4945 public static ActivityThread systemMain() {
4946 HardwareRenderer.disable(true);
4947 ActivityThread thread = new ActivityThread();
4948 thread.attach(true);
4952 public final void installSystemProviders(List<ProviderInfo> providers) {
4953 if (providers != null) {
4954 installContentProviders(mInitialApplication, providers);
4958 public int getIntCoreSetting(String key, int defaultValue) {
4959 synchronized (mResourcesManager) {
4960 if (mCoreSettings != null) {
4961 return mCoreSettings.getInt(key, defaultValue);
4963 return defaultValue;
4967 private static class EventLoggingReporter implements EventLogger.Reporter {
4969 public void report (int code, Object... list) {
4970 EventLog.writeEvent(code, list);
4974 private class DropBoxReporter implements DropBox.Reporter {
4976 private DropBoxManager dropBox;
4978 public DropBoxReporter() {
4979 dropBox = (DropBoxManager) getSystemContext().getSystemService(Context.DROPBOX_SERVICE);
4983 public void addData(String tag, byte[] data, int flags) {
4984 dropBox.addData(tag, data, flags);
4988 public void addText(String tag, String data) {
4989 dropBox.addText(tag, data);
4993 public static void main(String[] args) {
4994 SamplingProfilerIntegration.start();
4996 // CloseGuard defaults to true and can be quite spammy. We
4997 // disable it here, but selectively enable it later (via
4998 // StrictMode) on debug builds, but using DropBox, not logs.
4999 CloseGuard.setEnabled(false);
5001 Environment.initForCurrentUser();
5003 // Set the reporter for event logging in libcore
5004 EventLogger.setReporter(new EventLoggingReporter());
5006 Security.addProvider(new AndroidKeyStoreProvider());
5008 Process.setArgV0("<pre-initialized>");
5010 Looper.prepareMainLooper();
5012 ActivityThread thread = new ActivityThread();
5013 thread.attach(false);
5015 if (sMainThreadHandler == null) {
5016 sMainThreadHandler = thread.getHandler();
5022 Looper.myLooper().setMessageLogging(new
5023 LogPrinter(Log.DEBUG, "ActivityThread"));
5028 throw new RuntimeException("Main thread loop unexpectedly exited");