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.DisplayMetrics;
73 import android.util.EventLog;
74 import android.util.Log;
75 import android.util.LogPrinter;
76 import android.util.PrintWriterPrinter;
77 import android.util.Slog;
78 import android.view.CompatibilityInfoHolder;
79 import android.view.Display;
80 import android.view.HardwareRenderer;
81 import android.view.View;
82 import android.view.ViewDebug;
83 import android.view.ViewManager;
84 import android.view.ViewRootImpl;
85 import android.view.Window;
86 import android.view.WindowManager;
87 import android.view.WindowManagerGlobal;
88 import android.renderscript.RenderScript;
89 import android.security.AndroidKeyStoreProvider;
91 import com.android.internal.os.BinderInternal;
92 import com.android.internal.os.RuntimeInit;
93 import com.android.internal.os.SamplingProfilerIntegration;
94 import com.android.internal.util.Objects;
95 import com.android.org.conscrypt.OpenSSLSocketImpl;
98 import java.io.FileDescriptor;
99 import java.io.FileOutputStream;
100 import java.io.IOException;
101 import java.io.PrintWriter;
102 import java.lang.ref.WeakReference;
103 import java.net.InetAddress;
104 import java.security.Security;
105 import java.util.ArrayList;
106 import java.util.HashMap;
107 import java.util.Iterator;
108 import java.util.List;
109 import java.util.Locale;
110 import java.util.Map;
111 import java.util.TimeZone;
112 import java.util.regex.Pattern;
114 import libcore.io.DropBox;
115 import libcore.io.EventLogger;
116 import libcore.io.IoUtils;
118 import dalvik.system.CloseGuard;
120 final class SuperNotCalledException extends AndroidRuntimeException {
121 public SuperNotCalledException(String msg) {
126 final class RemoteServiceException extends AndroidRuntimeException {
127 public RemoteServiceException(String msg) {
133 * This manages the execution of the main thread in an
134 * application process, scheduling and executing activities,
135 * broadcasts, and other operations on it as the activity
140 public final class ActivityThread {
142 public static final String TAG = "ActivityThread";
143 private static final android.graphics.Bitmap.Config THUMBNAIL_FORMAT = Bitmap.Config.RGB_565;
144 static final boolean localLOGV = false;
145 static final boolean DEBUG_MESSAGES = false;
147 public static final boolean DEBUG_BROADCAST = false;
148 private static final boolean DEBUG_RESULTS = false;
149 private static final boolean DEBUG_BACKUP = false;
150 private static final boolean DEBUG_CONFIGURATION = false;
151 private static final boolean DEBUG_SERVICE = false;
152 private static final boolean DEBUG_MEMORY_TRIM = false;
153 private static final boolean DEBUG_PROVIDER = false;
154 private static final long MIN_TIME_BETWEEN_GCS = 5*1000;
155 private static final Pattern PATTERN_SEMICOLON = Pattern.compile(";");
156 private static final int SQLITE_MEM_RELEASED_EVENT_LOG_TAG = 75003;
157 private static final int LOG_ON_PAUSE_CALLED = 30021;
158 private static final int LOG_ON_RESUME_CALLED = 30022;
160 static ContextImpl mSystemContext = null;
162 static IPackageManager sPackageManager;
164 final ApplicationThread mAppThread = new ApplicationThread();
165 final Looper mLooper = Looper.myLooper();
166 final H mH = new H();
167 final HashMap<IBinder, ActivityClientRecord> mActivities
168 = new HashMap<IBinder, ActivityClientRecord>();
169 // List of new activities (via ActivityRecord.nextIdle) that should
170 // be reported when next we idle.
171 ActivityClientRecord mNewActivities = null;
172 // Number of activities that are currently visible on-screen.
173 int mNumVisibleActivities = 0;
174 final HashMap<IBinder, Service> mServices
175 = new HashMap<IBinder, Service>();
176 AppBindData mBoundApplication;
178 int mCurDefaultDisplayDpi;
179 boolean mDensityCompatMode;
180 Configuration mConfiguration;
181 Configuration mCompatConfiguration;
182 Configuration mResConfiguration;
183 CompatibilityInfo mResCompatibilityInfo;
184 Application mInitialApplication;
185 final ArrayList<Application> mAllApplications
186 = new ArrayList<Application>();
187 // set of instantiated backup agents, keyed by package name
188 final HashMap<String, BackupAgent> mBackupAgents = new HashMap<String, BackupAgent>();
189 /** Reference to singleton {@link ActivityThread} */
190 private static ActivityThread sCurrentActivityThread;
191 Instrumentation mInstrumentation;
192 String mInstrumentationAppDir = null;
193 String mInstrumentationAppLibraryDir = null;
194 String mInstrumentationAppPackage = null;
195 String mInstrumentedAppDir = null;
196 String mInstrumentedAppLibraryDir = null;
197 boolean mSystemThread = false;
198 boolean mJitEnabled = false;
200 // These can be accessed by multiple threads; mPackages is the lock.
201 // XXX For now we keep around information about all packages we have
202 // seen, not removing entries from this map.
203 // NOTE: The activity and window managers need to call in to
204 // ActivityThread to do things like update resource configurations,
205 // which means this lock gets held while the activity and window managers
206 // holds their own lock. Thus you MUST NEVER call back into the activity manager
207 // or window manager or anything that depends on them while holding this lock.
208 final HashMap<String, WeakReference<LoadedApk>> mPackages
209 = new HashMap<String, WeakReference<LoadedApk>>();
210 final HashMap<String, WeakReference<LoadedApk>> mResourcePackages
211 = new HashMap<String, WeakReference<LoadedApk>>();
212 final HashMap<CompatibilityInfo, DisplayMetrics> mDefaultDisplayMetrics
213 = new HashMap<CompatibilityInfo, DisplayMetrics>();
214 final HashMap<ResourcesKey, WeakReference<Resources> > mActiveResources
215 = new HashMap<ResourcesKey, WeakReference<Resources> >();
216 final ArrayList<ActivityClientRecord> mRelaunchingActivities
217 = new ArrayList<ActivityClientRecord>();
218 Configuration mPendingConfiguration = null;
220 private static final class ProviderKey {
221 final String authority;
224 public ProviderKey(String authority, int userId) {
225 this.authority = authority;
226 this.userId = userId;
230 public boolean equals(Object o) {
231 if (o instanceof ProviderKey) {
232 final ProviderKey other = (ProviderKey) o;
233 return Objects.equal(authority, other.authority) && userId == other.userId;
239 public int hashCode() {
240 return ((authority != null) ? authority.hashCode() : 0) ^ userId;
244 // The lock of mProviderMap protects the following variables.
245 final HashMap<ProviderKey, ProviderClientRecord> mProviderMap
246 = new HashMap<ProviderKey, ProviderClientRecord>();
247 final HashMap<IBinder, ProviderRefCount> mProviderRefCountMap
248 = new HashMap<IBinder, ProviderRefCount>();
249 final HashMap<IBinder, ProviderClientRecord> mLocalProviders
250 = new HashMap<IBinder, ProviderClientRecord>();
251 final HashMap<ComponentName, ProviderClientRecord> mLocalProvidersByName
252 = new HashMap<ComponentName, ProviderClientRecord>();
254 final HashMap<Activity, ArrayList<OnActivityPausedListener>> mOnPauseListeners
255 = new HashMap<Activity, ArrayList<OnActivityPausedListener>>();
257 final GcIdler mGcIdler = new GcIdler();
258 boolean mGcIdlerScheduled = false;
260 static Handler sMainThreadHandler; // set once in main()
262 Bundle mCoreSettings = null;
264 static final class ActivityClientRecord {
273 Activity.NonConfigurationInstances lastNonConfigurationInstances;
277 Configuration newConfig;
278 Configuration createdConfig;
279 ActivityClientRecord nextIdle;
282 ParcelFileDescriptor profileFd;
283 boolean autoStopProfiler;
285 ActivityInfo activityInfo;
286 CompatibilityInfo compatInfo;
287 LoadedApk packageInfo;
289 List<ResultInfo> pendingResults;
290 List<Intent> pendingIntents;
292 boolean startsNotResumed;
294 int pendingConfigChanges;
295 boolean onlyLocalRequest;
297 View mPendingRemoveWindow;
298 WindowManager mPendingRemoveWindowManager;
300 ActivityClientRecord() {
309 public boolean isPreHoneycomb() {
310 if (activity != null) {
311 return activity.getApplicationInfo().targetSdkVersion
312 < android.os.Build.VERSION_CODES.HONEYCOMB;
317 public String toString() {
318 ComponentName componentName = intent != null ? intent.getComponent() : null;
319 return "ActivityRecord{"
320 + Integer.toHexString(System.identityHashCode(this))
321 + " token=" + token + " " + (componentName == null
322 ? "no component name" : componentName.toShortString())
327 final class ProviderClientRecord {
328 final String[] mNames;
329 final IContentProvider mProvider;
330 final ContentProvider mLocalProvider;
331 final IActivityManager.ContentProviderHolder mHolder;
333 ProviderClientRecord(String[] names, IContentProvider provider,
334 ContentProvider localProvider,
335 IActivityManager.ContentProviderHolder holder) {
337 mProvider = provider;
338 mLocalProvider = localProvider;
343 static final class NewIntentData {
344 List<Intent> intents;
346 public String toString() {
347 return "NewIntentData{intents=" + intents + " token=" + token + "}";
351 static final class ReceiverData extends BroadcastReceiver.PendingResult {
352 public ReceiverData(Intent intent, int resultCode, String resultData, Bundle resultExtras,
353 boolean ordered, boolean sticky, IBinder token, int sendingUser) {
354 super(resultCode, resultData, resultExtras, TYPE_COMPONENT, ordered, sticky,
356 this.intent = intent;
361 CompatibilityInfo compatInfo;
362 public String toString() {
363 return "ReceiverData{intent=" + intent + " packageName=" +
364 info.packageName + " resultCode=" + getResultCode()
365 + " resultData=" + getResultData() + " resultExtras="
366 + getResultExtras(false) + "}";
370 static final class CreateBackupAgentData {
371 ApplicationInfo appInfo;
372 CompatibilityInfo compatInfo;
374 public String toString() {
375 return "CreateBackupAgentData{appInfo=" + appInfo
376 + " backupAgent=" + appInfo.backupAgentName
377 + " mode=" + backupMode + "}";
381 static final class CreateServiceData {
384 CompatibilityInfo compatInfo;
386 public String toString() {
387 return "CreateServiceData{token=" + token + " className="
388 + info.name + " packageName=" + info.packageName
389 + " intent=" + intent + "}";
393 static final class BindServiceData {
397 public String toString() {
398 return "BindServiceData{token=" + token + " intent=" + intent + "}";
402 static final class ServiceArgsData {
408 public String toString() {
409 return "ServiceArgsData{token=" + token + " startId=" + startId
410 + " args=" + args + "}";
414 static final class AppBindData {
417 ApplicationInfo appInfo;
418 List<ProviderInfo> providers;
419 ComponentName instrumentationName;
420 Bundle instrumentationArgs;
421 IInstrumentationWatcher instrumentationWatcher;
422 IUiAutomationConnection instrumentationUiAutomationConnection;
424 boolean enableOpenGlTrace;
425 boolean restrictedBackupMode;
427 Configuration config;
428 CompatibilityInfo compatInfo;
430 /** Initial values for {@link Profiler}. */
431 String initProfileFile;
432 ParcelFileDescriptor initProfileFd;
433 boolean initAutoStopProfiler;
435 public String toString() {
436 return "AppBindData{appInfo=" + appInfo + "}";
440 static final class Profiler {
442 ParcelFileDescriptor profileFd;
443 boolean autoStopProfiler;
445 boolean handlingProfiling;
446 public void setProfiler(String file, ParcelFileDescriptor fd) {
451 } catch (IOException e) {
457 if (profileFd != null) {
460 } catch (IOException e) {
467 public void startProfiling() {
468 if (profileFd == null || profiling) {
472 Debug.startMethodTracing(profileFile, profileFd.getFileDescriptor(),
475 } catch (RuntimeException e) {
476 Slog.w(TAG, "Profiling failed on path " + profileFile);
480 } catch (IOException e2) {
481 Slog.w(TAG, "Failure closing profile fd", e2);
485 public void stopProfiling() {
488 Debug.stopMethodTracing();
489 if (profileFd != null) {
492 } catch (IOException e) {
501 static final class DumpComponentInfo {
502 ParcelFileDescriptor fd;
508 static final class ResultData {
510 List<ResultInfo> results;
511 public String toString() {
512 return "ResultData{token=" + token + " results" + results + "}";
516 static final class ContextCleanupInfo {
522 static final class ProfilerControlData {
524 ParcelFileDescriptor fd;
527 static final class DumpHeapData {
529 ParcelFileDescriptor fd;
532 static final class UpdateCompatibilityData {
534 CompatibilityInfo info;
537 static final class RequestActivityExtras {
538 IBinder activityToken;
539 IBinder requestToken;
543 private native void dumpGraphicsInfo(FileDescriptor fd);
545 private class ApplicationThread extends ApplicationThreadNative {
546 private static final String HEAP_COLUMN = "%13s %8s %8s %8s %8s %8s %8s";
547 private static final String ONE_COUNT_COLUMN = "%21s %8d";
548 private static final String TWO_COUNT_COLUMNS = "%21s %8d %21s %8d";
549 private static final String DB_INFO_FORMAT = " %8s %8s %14s %14s %s";
551 // Formatting for checkin service - update version if row format changes
552 private static final int ACTIVITY_THREAD_CHECKIN_VERSION = 1;
554 private void updatePendingConfiguration(Configuration config) {
555 synchronized (mPackages) {
556 if (mPendingConfiguration == null ||
557 mPendingConfiguration.isOtherSeqNewer(config)) {
558 mPendingConfiguration = config;
563 public final void schedulePauseActivity(IBinder token, boolean finished,
564 boolean userLeaving, int configChanges) {
566 finished ? H.PAUSE_ACTIVITY_FINISHING : H.PAUSE_ACTIVITY,
568 (userLeaving ? 1 : 0),
572 public final void scheduleStopActivity(IBinder token, boolean showWindow,
575 showWindow ? H.STOP_ACTIVITY_SHOW : H.STOP_ACTIVITY_HIDE,
576 token, 0, configChanges);
579 public final void scheduleWindowVisibility(IBinder token, boolean showWindow) {
581 showWindow ? H.SHOW_WINDOW : H.HIDE_WINDOW,
585 public final void scheduleSleeping(IBinder token, boolean sleeping) {
586 queueOrSendMessage(H.SLEEPING, token, sleeping ? 1 : 0);
589 public final void scheduleResumeActivity(IBinder token, boolean isForward) {
590 queueOrSendMessage(H.RESUME_ACTIVITY, token, isForward ? 1 : 0);
593 public final void scheduleSendResult(IBinder token, List<ResultInfo> results) {
594 ResultData res = new ResultData();
596 res.results = results;
597 queueOrSendMessage(H.SEND_RESULT, res);
600 // we use token to identify this activity without having to send the
601 // activity itself back to the activity manager. (matters more with ipc)
602 public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
603 ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo,
604 Bundle state, List<ResultInfo> pendingResults,
605 List<Intent> pendingNewIntents, boolean notResumed, boolean isForward,
606 String profileName, ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
607 ActivityClientRecord r = new ActivityClientRecord();
612 r.activityInfo = info;
613 r.compatInfo = compatInfo;
616 r.pendingResults = pendingResults;
617 r.pendingIntents = pendingNewIntents;
619 r.startsNotResumed = notResumed;
620 r.isForward = isForward;
622 r.profileFile = profileName;
623 r.profileFd = profileFd;
624 r.autoStopProfiler = autoStopProfiler;
626 updatePendingConfiguration(curConfig);
628 queueOrSendMessage(H.LAUNCH_ACTIVITY, r);
631 public final void scheduleRelaunchActivity(IBinder token,
632 List<ResultInfo> pendingResults, List<Intent> pendingNewIntents,
633 int configChanges, boolean notResumed, Configuration config) {
634 requestRelaunchActivity(token, pendingResults, pendingNewIntents,
635 configChanges, notResumed, config, true);
638 public final void scheduleNewIntent(List<Intent> intents, IBinder token) {
639 NewIntentData data = new NewIntentData();
640 data.intents = intents;
643 queueOrSendMessage(H.NEW_INTENT, data);
646 public final void scheduleDestroyActivity(IBinder token, boolean finishing,
648 queueOrSendMessage(H.DESTROY_ACTIVITY, token, finishing ? 1 : 0,
652 public final void scheduleReceiver(Intent intent, ActivityInfo info,
653 CompatibilityInfo compatInfo, int resultCode, String data, Bundle extras,
654 boolean sync, int sendingUser) {
655 ReceiverData r = new ReceiverData(intent, resultCode, data, extras,
656 sync, false, mAppThread.asBinder(), sendingUser);
658 r.compatInfo = compatInfo;
659 queueOrSendMessage(H.RECEIVER, r);
662 public final void scheduleCreateBackupAgent(ApplicationInfo app,
663 CompatibilityInfo compatInfo, int backupMode) {
664 CreateBackupAgentData d = new CreateBackupAgentData();
666 d.compatInfo = compatInfo;
667 d.backupMode = backupMode;
669 queueOrSendMessage(H.CREATE_BACKUP_AGENT, d);
672 public final void scheduleDestroyBackupAgent(ApplicationInfo app,
673 CompatibilityInfo compatInfo) {
674 CreateBackupAgentData d = new CreateBackupAgentData();
676 d.compatInfo = compatInfo;
678 queueOrSendMessage(H.DESTROY_BACKUP_AGENT, d);
681 public final void scheduleCreateService(IBinder token,
682 ServiceInfo info, CompatibilityInfo compatInfo) {
683 CreateServiceData s = new CreateServiceData();
686 s.compatInfo = compatInfo;
688 queueOrSendMessage(H.CREATE_SERVICE, s);
691 public final void scheduleBindService(IBinder token, Intent intent,
693 BindServiceData s = new BindServiceData();
699 Slog.v(TAG, "scheduleBindService token=" + token + " intent=" + intent + " uid="
700 + Binder.getCallingUid() + " pid=" + Binder.getCallingPid());
701 queueOrSendMessage(H.BIND_SERVICE, s);
704 public final void scheduleUnbindService(IBinder token, Intent intent) {
705 BindServiceData s = new BindServiceData();
709 queueOrSendMessage(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 queueOrSendMessage(H.SERVICE_ARGS, s);
724 public final void scheduleStopService(IBinder token) {
725 queueOrSendMessage(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 AppBindData data = new AppBindData();
746 data.processName = processName;
747 data.appInfo = appInfo;
748 data.providers = providers;
749 data.instrumentationName = instrumentationName;
750 data.instrumentationArgs = instrumentationArgs;
751 data.instrumentationWatcher = instrumentationWatcher;
752 data.instrumentationUiAutomationConnection = instrumentationUiConnection;
753 data.debugMode = debugMode;
754 data.enableOpenGlTrace = enableOpenGlTrace;
755 data.restrictedBackupMode = isRestrictedBackupMode;
756 data.persistent = persistent;
757 data.config = config;
758 data.compatInfo = compatInfo;
759 data.initProfileFile = profileFile;
760 data.initProfileFd = profileFd;
761 data.initAutoStopProfiler = false;
762 queueOrSendMessage(H.BIND_APPLICATION, data);
765 public final void scheduleExit() {
766 queueOrSendMessage(H.EXIT_APPLICATION, null);
769 public final void scheduleSuicide() {
770 queueOrSendMessage(H.SUICIDE, null);
773 public void requestThumbnail(IBinder token) {
774 queueOrSendMessage(H.REQUEST_THUMBNAIL, token);
777 public void scheduleConfigurationChanged(Configuration config) {
778 updatePendingConfiguration(config);
779 queueOrSendMessage(H.CONFIGURATION_CHANGED, config);
782 public void updateTimeZone() {
783 TimeZone.setDefault(null);
786 public void clearDnsCache() {
787 // a non-standard API to get this to libcore
788 InetAddress.clearDnsCache();
791 public void setHttpProxy(String host, String port, String exclList) {
792 Proxy.setHttpProxySystemProperty(host, port, exclList);
795 public void processInBackground() {
796 mH.removeMessages(H.GC_WHEN_IDLE);
797 mH.sendMessage(mH.obtainMessage(H.GC_WHEN_IDLE));
800 public void dumpService(FileDescriptor fd, IBinder servicetoken, String[] args) {
801 DumpComponentInfo data = new DumpComponentInfo();
803 data.fd = ParcelFileDescriptor.dup(fd);
804 data.token = servicetoken;
806 queueOrSendMessage(H.DUMP_SERVICE, data);
807 } catch (IOException e) {
808 Slog.w(TAG, "dumpService failed", e);
812 // This function exists to make sure all receiver dispatching is
813 // correctly ordered, since these are one-way calls and the binder driver
814 // applies transaction ordering per object for such calls.
815 public void scheduleRegisteredReceiver(IIntentReceiver receiver, Intent intent,
816 int resultCode, String dataStr, Bundle extras, boolean ordered,
817 boolean sticky, int sendingUser) throws RemoteException {
818 receiver.performReceive(intent, resultCode, dataStr, extras, ordered,
819 sticky, sendingUser);
822 public void scheduleLowMemory() {
823 queueOrSendMessage(H.LOW_MEMORY, null);
826 public void scheduleActivityConfigurationChanged(IBinder token) {
827 queueOrSendMessage(H.ACTIVITY_CONFIGURATION_CHANGED, token);
830 public void profilerControl(boolean start, String path, ParcelFileDescriptor fd,
832 ProfilerControlData pcd = new ProfilerControlData();
835 queueOrSendMessage(H.PROFILER_CONTROL, pcd, start ? 1 : 0, profileType);
838 public void dumpHeap(boolean managed, String path, ParcelFileDescriptor fd) {
839 DumpHeapData dhd = new DumpHeapData();
842 queueOrSendMessage(H.DUMP_HEAP, dhd, managed ? 1 : 0);
845 public void setSchedulingGroup(int group) {
846 // Note: do this immediately, since going into the foreground
847 // should happen regardless of what pending work we have to do
848 // and the activity manager will wait for us to report back that
849 // we are done before sending us to the background.
851 Process.setProcessGroup(Process.myPid(), group);
852 } catch (Exception e) {
853 Slog.w(TAG, "Failed setting process group to " + group, e);
857 public void getMemoryInfo(Debug.MemoryInfo outInfo) {
858 Debug.getMemoryInfo(outInfo);
861 public void dispatchPackageBroadcast(int cmd, String[] packages) {
862 queueOrSendMessage(H.DISPATCH_PACKAGE_BROADCAST, packages, cmd);
865 public void scheduleCrash(String msg) {
866 queueOrSendMessage(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 queueOrSendMessage(H.DUMP_ACTIVITY, data);
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 queueOrSendMessage(H.DUMP_PROVIDER, data);
891 } catch (IOException e) {
892 Slog.w(TAG, "dumpProvider failed", e);
897 public Debug.MemoryInfo dumpMemInfo(FileDescriptor fd, boolean checkin,
898 boolean all, String[] args) {
899 FileOutputStream fout = new FileOutputStream(fd);
900 PrintWriter pw = new PrintWriter(fout);
902 return dumpMemInfo(pw, checkin, all);
908 private Debug.MemoryInfo dumpMemInfo(PrintWriter pw, boolean checkin, boolean all) {
909 long nativeMax = Debug.getNativeHeapSize() / 1024;
910 long nativeAllocated = Debug.getNativeHeapAllocatedSize() / 1024;
911 long nativeFree = Debug.getNativeHeapFreeSize() / 1024;
913 Debug.MemoryInfo memInfo = new Debug.MemoryInfo();
914 Debug.getMemoryInfo(memInfo);
920 Runtime runtime = Runtime.getRuntime();
922 long dalvikMax = runtime.totalMemory() / 1024;
923 long dalvikFree = runtime.freeMemory() / 1024;
924 long dalvikAllocated = dalvikMax - dalvikFree;
925 long viewInstanceCount = ViewDebug.getViewInstanceCount();
926 long viewRootInstanceCount = ViewDebug.getViewRootImplCount();
927 long appContextInstanceCount = Debug.countInstancesOfClass(ContextImpl.class);
928 long activityInstanceCount = Debug.countInstancesOfClass(Activity.class);
929 int globalAssetCount = AssetManager.getGlobalAssetCount();
930 int globalAssetManagerCount = AssetManager.getGlobalAssetManagerCount();
931 int binderLocalObjectCount = Debug.getBinderLocalObjectCount();
932 int binderProxyObjectCount = Debug.getBinderProxyObjectCount();
933 int binderDeathObjectCount = Debug.getBinderDeathObjectCount();
934 long openSslSocketCount = Debug.countInstancesOfClass(OpenSSLSocketImpl.class);
935 SQLiteDebug.PagerStats stats = SQLiteDebug.getDatabaseInfo();
937 // For checkin, we print one long comma-separated list of values
939 // NOTE: if you change anything significant below, also consider changing
940 // ACTIVITY_THREAD_CHECKIN_VERSION.
941 String processName = (mBoundApplication != null)
942 ? mBoundApplication.processName : "unknown";
945 pw.print(ACTIVITY_THREAD_CHECKIN_VERSION); pw.print(',');
946 pw.print(Process.myPid()); pw.print(',');
947 pw.print(processName); pw.print(',');
950 pw.print(nativeMax); pw.print(',');
951 pw.print(dalvikMax); pw.print(',');
953 pw.print(nativeMax + dalvikMax); pw.print(',');
955 // Heap info - allocated
956 pw.print(nativeAllocated); pw.print(',');
957 pw.print(dalvikAllocated); pw.print(',');
959 pw.print(nativeAllocated + dalvikAllocated); pw.print(',');
962 pw.print(nativeFree); pw.print(',');
963 pw.print(dalvikFree); pw.print(',');
965 pw.print(nativeFree + dalvikFree); pw.print(',');
967 // Heap info - proportional set size
968 pw.print(memInfo.nativePss); pw.print(',');
969 pw.print(memInfo.dalvikPss); pw.print(',');
970 pw.print(memInfo.otherPss); pw.print(',');
971 pw.print(memInfo.nativePss + memInfo.dalvikPss + memInfo.otherPss); pw.print(',');
973 // Heap info - shared
974 pw.print(memInfo.nativeSharedDirty); pw.print(',');
975 pw.print(memInfo.dalvikSharedDirty); pw.print(',');
976 pw.print(memInfo.otherSharedDirty); pw.print(',');
977 pw.print(memInfo.nativeSharedDirty + memInfo.dalvikSharedDirty
978 + memInfo.otherSharedDirty); pw.print(',');
980 // Heap info - private
981 pw.print(memInfo.nativePrivateDirty); pw.print(',');
982 pw.print(memInfo.dalvikPrivateDirty); pw.print(',');
983 pw.print(memInfo.otherPrivateDirty); pw.print(',');
984 pw.print(memInfo.nativePrivateDirty + memInfo.dalvikPrivateDirty
985 + memInfo.otherPrivateDirty); pw.print(',');
988 pw.print(viewInstanceCount); pw.print(',');
989 pw.print(viewRootInstanceCount); pw.print(',');
990 pw.print(appContextInstanceCount); pw.print(',');
991 pw.print(activityInstanceCount); pw.print(',');
993 pw.print(globalAssetCount); pw.print(',');
994 pw.print(globalAssetManagerCount); pw.print(',');
995 pw.print(binderLocalObjectCount); pw.print(',');
996 pw.print(binderProxyObjectCount); pw.print(',');
998 pw.print(binderDeathObjectCount); pw.print(',');
999 pw.print(openSslSocketCount); pw.print(',');
1002 pw.print(stats.memoryUsed / 1024); pw.print(',');
1003 pw.print(stats.memoryUsed / 1024); pw.print(',');
1004 pw.print(stats.pageCacheOverflow / 1024); pw.print(',');
1005 pw.print(stats.largestMemAlloc / 1024);
1006 for (int i = 0; i < stats.dbStats.size(); i++) {
1007 DbStats dbStats = stats.dbStats.get(i);
1008 pw.print(','); pw.print(dbStats.dbName);
1009 pw.print(','); pw.print(dbStats.pageSize);
1010 pw.print(','); pw.print(dbStats.dbSize);
1011 pw.print(','); pw.print(dbStats.lookaside);
1012 pw.print(','); pw.print(dbStats.cache);
1013 pw.print(','); pw.print(dbStats.cache);
1020 // otherwise, show human-readable format
1021 printRow(pw, HEAP_COLUMN, "", "", "Shared", "Private", "Heap", "Heap", "Heap");
1022 printRow(pw, HEAP_COLUMN, "", "Pss", "Dirty", "Dirty", "Size", "Alloc", "Free");
1023 printRow(pw, HEAP_COLUMN, "", "------", "------", "------", "------", "------",
1025 printRow(pw, HEAP_COLUMN, "Native", memInfo.nativePss, memInfo.nativeSharedDirty,
1026 memInfo.nativePrivateDirty, nativeMax, nativeAllocated, nativeFree);
1027 printRow(pw, HEAP_COLUMN, "Dalvik", memInfo.dalvikPss, memInfo.dalvikSharedDirty,
1028 memInfo.dalvikPrivateDirty, dalvikMax, dalvikAllocated, dalvikFree);
1030 int otherPss = memInfo.otherPss;
1031 int otherSharedDirty = memInfo.otherSharedDirty;
1032 int otherPrivateDirty = memInfo.otherPrivateDirty;
1034 for (int i=0; i<Debug.MemoryInfo.NUM_OTHER_STATS; i++) {
1035 printRow(pw, HEAP_COLUMN, Debug.MemoryInfo.getOtherLabel(i),
1036 memInfo.getOtherPss(i), memInfo.getOtherSharedDirty(i),
1037 memInfo.getOtherPrivateDirty(i), "", "", "");
1038 otherPss -= memInfo.getOtherPss(i);
1039 otherSharedDirty -= memInfo.getOtherSharedDirty(i);
1040 otherPrivateDirty -= memInfo.getOtherPrivateDirty(i);
1043 printRow(pw, HEAP_COLUMN, "Unknown", otherPss, otherSharedDirty,
1044 otherPrivateDirty, "", "", "");
1045 printRow(pw, HEAP_COLUMN, "TOTAL", memInfo.getTotalPss(),
1046 memInfo.getTotalSharedDirty(), memInfo.getTotalPrivateDirty(),
1047 nativeMax+dalvikMax, nativeAllocated+dalvikAllocated,
1048 nativeFree+dalvikFree);
1051 pw.println(" Objects");
1052 printRow(pw, TWO_COUNT_COLUMNS, "Views:", viewInstanceCount, "ViewRootImpl:",
1053 viewRootInstanceCount);
1055 printRow(pw, TWO_COUNT_COLUMNS, "AppContexts:", appContextInstanceCount,
1056 "Activities:", activityInstanceCount);
1058 printRow(pw, TWO_COUNT_COLUMNS, "Assets:", globalAssetCount,
1059 "AssetManagers:", globalAssetManagerCount);
1061 printRow(pw, TWO_COUNT_COLUMNS, "Local Binders:", binderLocalObjectCount,
1062 "Proxy Binders:", binderProxyObjectCount);
1063 printRow(pw, ONE_COUNT_COLUMN, "Death Recipients:", binderDeathObjectCount);
1065 printRow(pw, ONE_COUNT_COLUMN, "OpenSSL Sockets:", openSslSocketCount);
1070 printRow(pw, ONE_COUNT_COLUMN, "MEMORY_USED:", stats.memoryUsed / 1024);
1071 printRow(pw, TWO_COUNT_COLUMNS, "PAGECACHE_OVERFLOW:",
1072 stats.pageCacheOverflow / 1024, "MALLOC_SIZE:", stats.largestMemAlloc / 1024);
1074 int N = stats.dbStats.size();
1076 pw.println(" DATABASES");
1077 printRow(pw, " %8s %8s %14s %14s %s", "pgsz", "dbsz", "Lookaside(b)", "cache",
1079 for (int i = 0; i < N; i++) {
1080 DbStats dbStats = stats.dbStats.get(i);
1081 printRow(pw, DB_INFO_FORMAT,
1082 (dbStats.pageSize > 0) ? String.valueOf(dbStats.pageSize) : " ",
1083 (dbStats.dbSize > 0) ? String.valueOf(dbStats.dbSize) : " ",
1084 (dbStats.lookaside > 0) ? String.valueOf(dbStats.lookaside) : " ",
1085 dbStats.cache, dbStats.dbName);
1090 String assetAlloc = AssetManager.getAssetAllocations();
1091 if (assetAlloc != null) {
1093 pw.println(" Asset Allocations");
1094 pw.print(assetAlloc);
1101 public void dumpGfxInfo(FileDescriptor fd, String[] args) {
1102 dumpGraphicsInfo(fd);
1103 WindowManagerGlobal.getInstance().dumpGfxInfo(fd);
1107 public void dumpDbInfo(FileDescriptor fd, String[] args) {
1108 PrintWriter pw = new PrintWriter(new FileOutputStream(fd));
1109 PrintWriterPrinter printer = new PrintWriterPrinter(pw);
1110 SQLiteDebug.dump(printer, args);
1115 public void unstableProviderDied(IBinder provider) {
1116 queueOrSendMessage(H.UNSTABLE_PROVIDER_DIED, provider);
1120 public void requestActivityExtras(IBinder activityToken, IBinder requestToken,
1122 RequestActivityExtras cmd = new RequestActivityExtras();
1123 cmd.activityToken = activityToken;
1124 cmd.requestToken = requestToken;
1125 cmd.requestType = requestType;
1126 queueOrSendMessage(H.REQUEST_ACTIVITY_EXTRAS, cmd);
1129 private void printRow(PrintWriter pw, String format, Object...objs) {
1130 pw.println(String.format(format, objs));
1133 public void setCoreSettings(Bundle coreSettings) {
1134 queueOrSendMessage(H.SET_CORE_SETTINGS, coreSettings);
1137 public void updatePackageCompatibilityInfo(String pkg, CompatibilityInfo info) {
1138 UpdateCompatibilityData ucd = new UpdateCompatibilityData();
1141 queueOrSendMessage(H.UPDATE_PACKAGE_COMPATIBILITY_INFO, ucd);
1144 public void scheduleTrimMemory(int level) {
1145 queueOrSendMessage(H.TRIM_MEMORY, null, level);
1150 private class H extends Handler {
1151 public static final int LAUNCH_ACTIVITY = 100;
1152 public static final int PAUSE_ACTIVITY = 101;
1153 public static final int PAUSE_ACTIVITY_FINISHING= 102;
1154 public static final int STOP_ACTIVITY_SHOW = 103;
1155 public static final int STOP_ACTIVITY_HIDE = 104;
1156 public static final int SHOW_WINDOW = 105;
1157 public static final int HIDE_WINDOW = 106;
1158 public static final int RESUME_ACTIVITY = 107;
1159 public static final int SEND_RESULT = 108;
1160 public static final int DESTROY_ACTIVITY = 109;
1161 public static final int BIND_APPLICATION = 110;
1162 public static final int EXIT_APPLICATION = 111;
1163 public static final int NEW_INTENT = 112;
1164 public static final int RECEIVER = 113;
1165 public static final int CREATE_SERVICE = 114;
1166 public static final int SERVICE_ARGS = 115;
1167 public static final int STOP_SERVICE = 116;
1168 public static final int REQUEST_THUMBNAIL = 117;
1169 public static final int CONFIGURATION_CHANGED = 118;
1170 public static final int CLEAN_UP_CONTEXT = 119;
1171 public static final int GC_WHEN_IDLE = 120;
1172 public static final int BIND_SERVICE = 121;
1173 public static final int UNBIND_SERVICE = 122;
1174 public static final int DUMP_SERVICE = 123;
1175 public static final int LOW_MEMORY = 124;
1176 public static final int ACTIVITY_CONFIGURATION_CHANGED = 125;
1177 public static final int RELAUNCH_ACTIVITY = 126;
1178 public static final int PROFILER_CONTROL = 127;
1179 public static final int CREATE_BACKUP_AGENT = 128;
1180 public static final int DESTROY_BACKUP_AGENT = 129;
1181 public static final int SUICIDE = 130;
1182 public static final int REMOVE_PROVIDER = 131;
1183 public static final int ENABLE_JIT = 132;
1184 public static final int DISPATCH_PACKAGE_BROADCAST = 133;
1185 public static final int SCHEDULE_CRASH = 134;
1186 public static final int DUMP_HEAP = 135;
1187 public static final int DUMP_ACTIVITY = 136;
1188 public static final int SLEEPING = 137;
1189 public static final int SET_CORE_SETTINGS = 138;
1190 public static final int UPDATE_PACKAGE_COMPATIBILITY_INFO = 139;
1191 public static final int TRIM_MEMORY = 140;
1192 public static final int DUMP_PROVIDER = 141;
1193 public static final int UNSTABLE_PROVIDER_DIED = 142;
1194 public static final int REQUEST_ACTIVITY_EXTRAS = 143;
1195 String codeToString(int code) {
1196 if (DEBUG_MESSAGES) {
1198 case LAUNCH_ACTIVITY: return "LAUNCH_ACTIVITY";
1199 case PAUSE_ACTIVITY: return "PAUSE_ACTIVITY";
1200 case PAUSE_ACTIVITY_FINISHING: return "PAUSE_ACTIVITY_FINISHING";
1201 case STOP_ACTIVITY_SHOW: return "STOP_ACTIVITY_SHOW";
1202 case STOP_ACTIVITY_HIDE: return "STOP_ACTIVITY_HIDE";
1203 case SHOW_WINDOW: return "SHOW_WINDOW";
1204 case HIDE_WINDOW: return "HIDE_WINDOW";
1205 case RESUME_ACTIVITY: return "RESUME_ACTIVITY";
1206 case SEND_RESULT: return "SEND_RESULT";
1207 case DESTROY_ACTIVITY: return "DESTROY_ACTIVITY";
1208 case BIND_APPLICATION: return "BIND_APPLICATION";
1209 case EXIT_APPLICATION: return "EXIT_APPLICATION";
1210 case NEW_INTENT: return "NEW_INTENT";
1211 case RECEIVER: return "RECEIVER";
1212 case CREATE_SERVICE: return "CREATE_SERVICE";
1213 case SERVICE_ARGS: return "SERVICE_ARGS";
1214 case STOP_SERVICE: return "STOP_SERVICE";
1215 case REQUEST_THUMBNAIL: return "REQUEST_THUMBNAIL";
1216 case CONFIGURATION_CHANGED: return "CONFIGURATION_CHANGED";
1217 case CLEAN_UP_CONTEXT: return "CLEAN_UP_CONTEXT";
1218 case GC_WHEN_IDLE: return "GC_WHEN_IDLE";
1219 case BIND_SERVICE: return "BIND_SERVICE";
1220 case UNBIND_SERVICE: return "UNBIND_SERVICE";
1221 case DUMP_SERVICE: return "DUMP_SERVICE";
1222 case LOW_MEMORY: return "LOW_MEMORY";
1223 case ACTIVITY_CONFIGURATION_CHANGED: return "ACTIVITY_CONFIGURATION_CHANGED";
1224 case RELAUNCH_ACTIVITY: return "RELAUNCH_ACTIVITY";
1225 case PROFILER_CONTROL: return "PROFILER_CONTROL";
1226 case CREATE_BACKUP_AGENT: return "CREATE_BACKUP_AGENT";
1227 case DESTROY_BACKUP_AGENT: return "DESTROY_BACKUP_AGENT";
1228 case SUICIDE: return "SUICIDE";
1229 case REMOVE_PROVIDER: return "REMOVE_PROVIDER";
1230 case ENABLE_JIT: return "ENABLE_JIT";
1231 case DISPATCH_PACKAGE_BROADCAST: return "DISPATCH_PACKAGE_BROADCAST";
1232 case SCHEDULE_CRASH: return "SCHEDULE_CRASH";
1233 case DUMP_HEAP: return "DUMP_HEAP";
1234 case DUMP_ACTIVITY: return "DUMP_ACTIVITY";
1235 case SLEEPING: return "SLEEPING";
1236 case SET_CORE_SETTINGS: return "SET_CORE_SETTINGS";
1237 case UPDATE_PACKAGE_COMPATIBILITY_INFO: return "UPDATE_PACKAGE_COMPATIBILITY_INFO";
1238 case TRIM_MEMORY: return "TRIM_MEMORY";
1239 case DUMP_PROVIDER: return "DUMP_PROVIDER";
1240 case UNSTABLE_PROVIDER_DIED: return "UNSTABLE_PROVIDER_DIED";
1241 case REQUEST_ACTIVITY_EXTRAS: return "REQUEST_ACTIVITY_EXTRAS";
1244 return Integer.toString(code);
1246 public void handleMessage(Message msg) {
1247 if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
1249 case LAUNCH_ACTIVITY: {
1250 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
1251 ActivityClientRecord r = (ActivityClientRecord)msg.obj;
1253 r.packageInfo = getPackageInfoNoCheck(
1254 r.activityInfo.applicationInfo, r.compatInfo);
1255 handleLaunchActivity(r, null);
1256 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1258 case RELAUNCH_ACTIVITY: {
1259 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityRestart");
1260 ActivityClientRecord r = (ActivityClientRecord)msg.obj;
1261 handleRelaunchActivity(r);
1262 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1264 case PAUSE_ACTIVITY:
1265 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
1266 handlePauseActivity((IBinder)msg.obj, false, msg.arg1 != 0, msg.arg2);
1268 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1270 case PAUSE_ACTIVITY_FINISHING:
1271 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
1272 handlePauseActivity((IBinder)msg.obj, true, msg.arg1 != 0, msg.arg2);
1273 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1275 case STOP_ACTIVITY_SHOW:
1276 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStop");
1277 handleStopActivity((IBinder)msg.obj, true, msg.arg2);
1278 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1280 case STOP_ACTIVITY_HIDE:
1281 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStop");
1282 handleStopActivity((IBinder)msg.obj, false, msg.arg2);
1283 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1286 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityShowWindow");
1287 handleWindowVisibility((IBinder)msg.obj, true);
1288 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1291 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityHideWindow");
1292 handleWindowVisibility((IBinder)msg.obj, false);
1293 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1295 case RESUME_ACTIVITY:
1296 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityResume");
1297 handleResumeActivity((IBinder)msg.obj, true,
1298 msg.arg1 != 0, true);
1299 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1302 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityDeliverResult");
1303 handleSendResult((ResultData)msg.obj);
1304 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1306 case DESTROY_ACTIVITY:
1307 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityDestroy");
1308 handleDestroyActivity((IBinder)msg.obj, msg.arg1 != 0,
1310 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1312 case BIND_APPLICATION:
1313 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
1314 AppBindData data = (AppBindData)msg.obj;
1315 handleBindApplication(data);
1316 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1318 case EXIT_APPLICATION:
1319 if (mInitialApplication != null) {
1320 mInitialApplication.onTerminate();
1322 Looper.myLooper().quit();
1325 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityNewIntent");
1326 handleNewIntent((NewIntentData)msg.obj);
1327 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1330 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "broadcastReceiveComp");
1331 handleReceiver((ReceiverData)msg.obj);
1333 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1335 case CREATE_SERVICE:
1336 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceCreate");
1337 handleCreateService((CreateServiceData)msg.obj);
1338 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1341 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceBind");
1342 handleBindService((BindServiceData)msg.obj);
1343 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1345 case UNBIND_SERVICE:
1346 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceUnbind");
1347 handleUnbindService((BindServiceData)msg.obj);
1348 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1351 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceStart");
1352 handleServiceArgs((ServiceArgsData)msg.obj);
1353 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1356 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceStop");
1357 handleStopService((IBinder)msg.obj);
1359 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1361 case REQUEST_THUMBNAIL:
1362 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "requestThumbnail");
1363 handleRequestThumbnail((IBinder)msg.obj);
1364 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1366 case CONFIGURATION_CHANGED:
1367 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "configChanged");
1368 mCurDefaultDisplayDpi = ((Configuration)msg.obj).densityDpi;
1369 handleConfigurationChanged((Configuration)msg.obj, null);
1370 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1372 case CLEAN_UP_CONTEXT:
1373 ContextCleanupInfo cci = (ContextCleanupInfo)msg.obj;
1374 cci.context.performFinalCleanup(cci.who, cci.what);
1380 handleDumpService((DumpComponentInfo)msg.obj);
1383 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "lowMemory");
1385 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1387 case ACTIVITY_CONFIGURATION_CHANGED:
1388 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityConfigChanged");
1389 handleActivityConfigurationChanged((IBinder)msg.obj);
1390 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1392 case PROFILER_CONTROL:
1393 handleProfilerControl(msg.arg1 != 0, (ProfilerControlData)msg.obj, msg.arg2);
1395 case CREATE_BACKUP_AGENT:
1396 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "backupCreateAgent");
1397 handleCreateBackupAgent((CreateBackupAgentData)msg.obj);
1398 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1400 case DESTROY_BACKUP_AGENT:
1401 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "backupDestroyAgent");
1402 handleDestroyBackupAgent((CreateBackupAgentData)msg.obj);
1403 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1406 Process.killProcess(Process.myPid());
1408 case REMOVE_PROVIDER:
1409 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "providerRemove");
1410 completeRemoveProvider((ProviderRefCount)msg.obj);
1411 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1416 case DISPATCH_PACKAGE_BROADCAST:
1417 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "broadcastPackage");
1418 handleDispatchPackageBroadcast(msg.arg1, (String[])msg.obj);
1419 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1421 case SCHEDULE_CRASH:
1422 throw new RemoteServiceException((String)msg.obj);
1424 handleDumpHeap(msg.arg1 != 0, (DumpHeapData)msg.obj);
1427 handleDumpActivity((DumpComponentInfo)msg.obj);
1430 handleDumpProvider((DumpComponentInfo)msg.obj);
1433 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "sleeping");
1434 handleSleeping((IBinder)msg.obj, msg.arg1 != 0);
1435 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1437 case SET_CORE_SETTINGS:
1438 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "setCoreSettings");
1439 handleSetCoreSettings((Bundle) msg.obj);
1440 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1442 case UPDATE_PACKAGE_COMPATIBILITY_INFO:
1443 handleUpdatePackageCompatibilityInfo((UpdateCompatibilityData)msg.obj);
1446 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "trimMemory");
1447 handleTrimMemory(msg.arg1);
1448 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1450 case UNSTABLE_PROVIDER_DIED:
1451 handleUnstableProviderDied((IBinder)msg.obj, false);
1453 case REQUEST_ACTIVITY_EXTRAS:
1454 handleRequestActivityExtras((RequestActivityExtras)msg.obj);
1457 if (DEBUG_MESSAGES) Slog.v(TAG, "<<< done: " + codeToString(msg.what));
1460 private void maybeSnapshot() {
1461 if (mBoundApplication != null && SamplingProfilerIntegration.isEnabled()) {
1462 // convert the *private* ActivityThread.PackageInfo to *public* known
1463 // android.content.pm.PackageInfo
1464 String packageName = mBoundApplication.info.mPackageName;
1465 android.content.pm.PackageInfo packageInfo = null;
1467 Context context = getSystemContext();
1468 if(context == null) {
1469 Log.e(TAG, "cannot get a valid context");
1472 PackageManager pm = context.getPackageManager();
1474 Log.e(TAG, "cannot get a valid PackageManager");
1477 packageInfo = pm.getPackageInfo(
1478 packageName, PackageManager.GET_ACTIVITIES);
1479 } catch (NameNotFoundException e) {
1480 Log.e(TAG, "cannot get package info for " + packageName, e);
1482 SamplingProfilerIntegration.writeSnapshot(mBoundApplication.processName, packageInfo);
1487 private class Idler implements MessageQueue.IdleHandler {
1488 public final boolean queueIdle() {
1489 ActivityClientRecord a = mNewActivities;
1490 boolean stopProfiling = false;
1491 if (mBoundApplication != null && mProfiler.profileFd != null
1492 && mProfiler.autoStopProfiler) {
1493 stopProfiling = true;
1496 mNewActivities = null;
1497 IActivityManager am = ActivityManagerNative.getDefault();
1498 ActivityClientRecord prev;
1500 if (localLOGV) Slog.v(
1501 TAG, "Reporting idle of " + a +
1503 (a.activity != null && a.activity.mFinished));
1504 if (a.activity != null && !a.activity.mFinished) {
1506 am.activityIdle(a.token, a.createdConfig, stopProfiling);
1507 a.createdConfig = null;
1508 } catch (RemoteException ex) {
1514 prev.nextIdle = null;
1515 } while (a != null);
1517 if (stopProfiling) {
1518 mProfiler.stopProfiling();
1525 final class GcIdler implements MessageQueue.IdleHandler {
1526 public final boolean queueIdle() {
1532 private static class ResourcesKey {
1533 final private String mResDir;
1534 final private int mDisplayId;
1535 final private Configuration mOverrideConfiguration;
1536 final private float mScale;
1537 final private int mHash;
1539 ResourcesKey(String resDir, int displayId, Configuration overrideConfiguration, float scale) {
1541 mDisplayId = displayId;
1542 if (overrideConfiguration != null) {
1543 if (Configuration.EMPTY.equals(overrideConfiguration)) {
1544 overrideConfiguration = null;
1547 mOverrideConfiguration = overrideConfiguration;
1550 hash = 31 * hash + mResDir.hashCode();
1551 hash = 31 * hash + mDisplayId;
1552 hash = 31 * hash + (mOverrideConfiguration != null
1553 ? mOverrideConfiguration.hashCode() : 0);
1554 hash = 31 * hash + Float.floatToIntBits(mScale);
1559 public int hashCode() {
1564 public boolean equals(Object obj) {
1565 if (!(obj instanceof ResourcesKey)) {
1568 ResourcesKey peer = (ResourcesKey) obj;
1569 if (!mResDir.equals(peer.mResDir)) {
1572 if (mDisplayId != peer.mDisplayId) {
1575 if (mOverrideConfiguration != peer.mOverrideConfiguration) {
1576 if (mOverrideConfiguration == null || peer.mOverrideConfiguration == null) {
1579 if (!mOverrideConfiguration.equals(peer.mOverrideConfiguration)) {
1583 if (mScale != peer.mScale) {
1590 public static ActivityThread currentActivityThread() {
1591 return sCurrentActivityThread;
1594 public static String currentPackageName() {
1595 ActivityThread am = currentActivityThread();
1596 return (am != null && am.mBoundApplication != null)
1597 ? am.mBoundApplication.appInfo.packageName : null;
1600 public static String currentProcessName() {
1601 ActivityThread am = currentActivityThread();
1602 return (am != null && am.mBoundApplication != null)
1603 ? am.mBoundApplication.processName : null;
1606 public static Application currentApplication() {
1607 ActivityThread am = currentActivityThread();
1608 return am != null ? am.mInitialApplication : null;
1611 public static IPackageManager getPackageManager() {
1612 if (sPackageManager != null) {
1613 //Slog.v("PackageManager", "returning cur default = " + sPackageManager);
1614 return sPackageManager;
1616 IBinder b = ServiceManager.getService("package");
1617 //Slog.v("PackageManager", "default service binder = " + b);
1618 sPackageManager = IPackageManager.Stub.asInterface(b);
1619 //Slog.v("PackageManager", "default service = " + sPackageManager);
1620 return sPackageManager;
1623 private void flushDisplayMetricsLocked() {
1624 mDefaultDisplayMetrics.clear();
1627 DisplayMetrics getDisplayMetricsLocked(int displayId, CompatibilityInfo ci) {
1628 boolean isDefaultDisplay = (displayId == Display.DEFAULT_DISPLAY);
1629 DisplayMetrics dm = isDefaultDisplay ? mDefaultDisplayMetrics.get(ci) : null;
1633 dm = new DisplayMetrics();
1635 DisplayManagerGlobal displayManager = DisplayManagerGlobal.getInstance();
1636 if (displayManager == null) {
1637 // may be null early in system startup
1642 if (isDefaultDisplay) {
1643 mDefaultDisplayMetrics.put(ci, dm);
1646 CompatibilityInfoHolder cih = new CompatibilityInfoHolder();
1648 Display d = displayManager.getCompatibleDisplay(displayId, cih);
1652 // Display no longer exists
1653 // FIXME: This would not be a problem if we kept the Display object around
1654 // instead of using the raw display id everywhere. The Display object caches
1655 // its information even after the display has been removed.
1658 //Slog.i("foo", "New metrics: w=" + metrics.widthPixels + " h="
1659 // + metrics.heightPixels + " den=" + metrics.density
1660 // + " xdpi=" + metrics.xdpi + " ydpi=" + metrics.ydpi);
1664 private Configuration mMainThreadConfig = new Configuration();
1665 Configuration applyConfigCompatMainThread(int displayDensity, Configuration config,
1666 CompatibilityInfo compat) {
1667 if (config == null) {
1670 if (compat != null && !compat.supportsScreen()) {
1671 mMainThreadConfig.setTo(config);
1672 config = mMainThreadConfig;
1673 compat.applyToConfiguration(displayDensity, config);
1679 * Creates the top level Resources for applications with the given compatibility info.
1681 * @param resDir the resource directory.
1682 * @param compInfo the compability info. It will use the default compatibility info when it's
1685 Resources getTopLevelResources(String resDir,
1686 int displayId, Configuration overrideConfiguration,
1687 CompatibilityInfo compInfo) {
1688 ResourcesKey key = new ResourcesKey(resDir,
1689 displayId, overrideConfiguration,
1690 compInfo.applicationScale);
1692 synchronized (mPackages) {
1693 // Resources is app scale dependent.
1695 Slog.w(TAG, "getTopLevelResources: " + resDir + " / "
1696 + compInfo.applicationScale);
1698 WeakReference<Resources> wr = mActiveResources.get(key);
1699 r = wr != null ? wr.get() : null;
1700 //if (r != null) Slog.i(TAG, "isUpToDate " + resDir + ": " + r.getAssets().isUpToDate());
1701 if (r != null && r.getAssets().isUpToDate()) {
1703 Slog.w(TAG, "Returning cached resources " + r + " " + resDir
1704 + ": appScale=" + r.getCompatibilityInfo().applicationScale);
1711 // Slog.w(TAG, "Throwing away out-of-date resources!!!! "
1712 // + r + " " + resDir);
1715 AssetManager assets = new AssetManager();
1716 if (assets.addAssetPath(resDir) == 0) {
1720 //Slog.i(TAG, "Resource: key=" + key + ", display metrics=" + metrics);
1721 DisplayMetrics dm = getDisplayMetricsLocked(displayId, null);
1722 Configuration config;
1723 boolean isDefaultDisplay = (displayId == Display.DEFAULT_DISPLAY);
1724 if (!isDefaultDisplay || key.mOverrideConfiguration != null) {
1725 config = new Configuration(getConfiguration());
1726 if (!isDefaultDisplay) {
1727 applyNonDefaultDisplayMetricsToConfigurationLocked(dm, config);
1729 if (key.mOverrideConfiguration != null) {
1730 config.updateFrom(key.mOverrideConfiguration);
1733 config = getConfiguration();
1735 r = new Resources(assets, dm, config, compInfo);
1737 Slog.i(TAG, "Created app resources " + resDir + " " + r + ": "
1738 + r.getConfiguration() + " appScale="
1739 + r.getCompatibilityInfo().applicationScale);
1742 synchronized (mPackages) {
1743 WeakReference<Resources> wr = mActiveResources.get(key);
1744 Resources existing = wr != null ? wr.get() : null;
1745 if (existing != null && existing.getAssets().isUpToDate()) {
1746 // Someone else already created the resources while we were
1747 // unlocked; go ahead and use theirs.
1748 r.getAssets().close();
1752 // XXX need to remove entries when weak references go away
1753 mActiveResources.put(key, new WeakReference<Resources>(r));
1759 * Creates the top level resources for the given package.
1761 Resources getTopLevelResources(String resDir,
1762 int displayId, Configuration overrideConfiguration,
1763 LoadedApk pkgInfo) {
1764 return getTopLevelResources(resDir, displayId, overrideConfiguration,
1765 pkgInfo.mCompatibilityInfo.get());
1768 final Handler getHandler() {
1772 public final LoadedApk getPackageInfo(String packageName, CompatibilityInfo compatInfo,
1774 return getPackageInfo(packageName, compatInfo, flags, UserHandle.myUserId());
1777 public final LoadedApk getPackageInfo(String packageName, CompatibilityInfo compatInfo,
1778 int flags, int userId) {
1779 synchronized (mPackages) {
1780 WeakReference<LoadedApk> ref;
1781 if ((flags&Context.CONTEXT_INCLUDE_CODE) != 0) {
1782 ref = mPackages.get(packageName);
1784 ref = mResourcePackages.get(packageName);
1786 LoadedApk packageInfo = ref != null ? ref.get() : null;
1787 //Slog.i(TAG, "getPackageInfo " + packageName + ": " + packageInfo);
1788 //if (packageInfo != null) Slog.i(TAG, "isUptoDate " + packageInfo.mResDir
1789 // + ": " + packageInfo.mResources.getAssets().isUpToDate());
1790 if (packageInfo != null && (packageInfo.mResources == null
1791 || packageInfo.mResources.getAssets().isUpToDate())) {
1792 if (packageInfo.isSecurityViolation()
1793 && (flags&Context.CONTEXT_IGNORE_SECURITY) == 0) {
1794 throw new SecurityException(
1795 "Requesting code from " + packageName
1796 + " to be run in process "
1797 + mBoundApplication.processName
1798 + "/" + mBoundApplication.appInfo.uid);
1804 ApplicationInfo ai = null;
1806 ai = getPackageManager().getApplicationInfo(packageName,
1807 PackageManager.GET_SHARED_LIBRARY_FILES, userId);
1808 } catch (RemoteException e) {
1813 return getPackageInfo(ai, compatInfo, flags);
1819 public final LoadedApk getPackageInfo(ApplicationInfo ai, CompatibilityInfo compatInfo,
1821 boolean includeCode = (flags&Context.CONTEXT_INCLUDE_CODE) != 0;
1822 boolean securityViolation = includeCode && ai.uid != 0
1823 && ai.uid != Process.SYSTEM_UID && (mBoundApplication != null
1824 ? !UserHandle.isSameApp(ai.uid, mBoundApplication.appInfo.uid)
1826 if ((flags&(Context.CONTEXT_INCLUDE_CODE
1827 |Context.CONTEXT_IGNORE_SECURITY))
1828 == Context.CONTEXT_INCLUDE_CODE) {
1829 if (securityViolation) {
1830 String msg = "Requesting code from " + ai.packageName
1831 + " (with uid " + ai.uid + ")";
1832 if (mBoundApplication != null) {
1833 msg = msg + " to be run in process "
1834 + mBoundApplication.processName + " (with uid "
1835 + mBoundApplication.appInfo.uid + ")";
1837 throw new SecurityException(msg);
1840 return getPackageInfo(ai, compatInfo, null, securityViolation, includeCode);
1843 public final LoadedApk getPackageInfoNoCheck(ApplicationInfo ai,
1844 CompatibilityInfo compatInfo) {
1845 return getPackageInfo(ai, compatInfo, null, false, true);
1848 public final LoadedApk peekPackageInfo(String packageName, boolean includeCode) {
1849 synchronized (mPackages) {
1850 WeakReference<LoadedApk> ref;
1852 ref = mPackages.get(packageName);
1854 ref = mResourcePackages.get(packageName);
1856 return ref != null ? ref.get() : null;
1860 private LoadedApk getPackageInfo(ApplicationInfo aInfo, CompatibilityInfo compatInfo,
1861 ClassLoader baseLoader, boolean securityViolation, boolean includeCode) {
1862 synchronized (mPackages) {
1863 WeakReference<LoadedApk> ref;
1865 ref = mPackages.get(aInfo.packageName);
1867 ref = mResourcePackages.get(aInfo.packageName);
1869 LoadedApk packageInfo = ref != null ? ref.get() : null;
1870 if (packageInfo == null || (packageInfo.mResources != null
1871 && !packageInfo.mResources.getAssets().isUpToDate())) {
1872 if (localLOGV) Slog.v(TAG, (includeCode ? "Loading code package "
1873 : "Loading resource-only package ") + aInfo.packageName
1874 + " (in " + (mBoundApplication != null
1875 ? mBoundApplication.processName : null)
1878 new LoadedApk(this, aInfo, compatInfo, this, baseLoader,
1879 securityViolation, includeCode &&
1880 (aInfo.flags&ApplicationInfo.FLAG_HAS_CODE) != 0);
1882 mPackages.put(aInfo.packageName,
1883 new WeakReference<LoadedApk>(packageInfo));
1885 mResourcePackages.put(aInfo.packageName,
1886 new WeakReference<LoadedApk>(packageInfo));
1896 public ApplicationThread getApplicationThread()
1901 public Instrumentation getInstrumentation()
1903 return mInstrumentation;
1906 public Configuration getConfiguration() {
1907 return mResConfiguration;
1910 public boolean isProfiling() {
1911 return mProfiler != null && mProfiler.profileFile != null
1912 && mProfiler.profileFd == null;
1915 public String getProfileFilePath() {
1916 return mProfiler.profileFile;
1919 public Looper getLooper() {
1923 public Application getApplication() {
1924 return mInitialApplication;
1927 public String getProcessName() {
1928 return mBoundApplication.processName;
1931 public ContextImpl getSystemContext() {
1932 synchronized (this) {
1933 if (mSystemContext == null) {
1934 ContextImpl context =
1935 ContextImpl.createSystemContext(this);
1936 LoadedApk info = new LoadedApk(this, "android", context, null,
1937 CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO);
1938 context.init(info, null, this);
1939 context.getResources().updateConfiguration(
1940 getConfiguration(), getDisplayMetricsLocked(
1941 Display.DEFAULT_DISPLAY,
1942 CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO));
1943 mSystemContext = context;
1944 //Slog.i(TAG, "Created system resources " + context.getResources()
1945 // + ": " + context.getResources().getConfiguration());
1948 return mSystemContext;
1951 public void installSystemApplicationInfo(ApplicationInfo info) {
1952 synchronized (this) {
1953 ContextImpl context = getSystemContext();
1954 context.init(new LoadedApk(this, "android", context, info,
1955 CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO), null, this);
1957 // give ourselves a default profiler
1958 mProfiler = new Profiler();
1962 void ensureJitEnabled() {
1965 dalvik.system.VMRuntime.getRuntime().startJitCompilation();
1969 void scheduleGcIdler() {
1970 if (!mGcIdlerScheduled) {
1971 mGcIdlerScheduled = true;
1972 Looper.myQueue().addIdleHandler(mGcIdler);
1974 mH.removeMessages(H.GC_WHEN_IDLE);
1977 void unscheduleGcIdler() {
1978 if (mGcIdlerScheduled) {
1979 mGcIdlerScheduled = false;
1980 Looper.myQueue().removeIdleHandler(mGcIdler);
1982 mH.removeMessages(H.GC_WHEN_IDLE);
1985 void doGcIfNeeded() {
1986 mGcIdlerScheduled = false;
1987 final long now = SystemClock.uptimeMillis();
1988 //Slog.i(TAG, "**** WE MIGHT WANT TO GC: then=" + Binder.getLastGcTime()
1989 // + "m now=" + now);
1990 if ((BinderInternal.getLastGcTime()+MIN_TIME_BETWEEN_GCS) < now) {
1991 //Slog.i(TAG, "**** WE DO, WE DO WANT TO GC!");
1992 BinderInternal.forceGc("bg");
1996 public void registerOnActivityPausedListener(Activity activity,
1997 OnActivityPausedListener listener) {
1998 synchronized (mOnPauseListeners) {
1999 ArrayList<OnActivityPausedListener> list = mOnPauseListeners.get(activity);
2001 list = new ArrayList<OnActivityPausedListener>();
2002 mOnPauseListeners.put(activity, list);
2008 public void unregisterOnActivityPausedListener(Activity activity,
2009 OnActivityPausedListener listener) {
2010 synchronized (mOnPauseListeners) {
2011 ArrayList<OnActivityPausedListener> list = mOnPauseListeners.get(activity);
2013 list.remove(listener);
2018 public final ActivityInfo resolveActivityInfo(Intent intent) {
2019 ActivityInfo aInfo = intent.resolveActivityInfo(
2020 mInitialApplication.getPackageManager(), PackageManager.GET_SHARED_LIBRARY_FILES);
2021 if (aInfo == null) {
2022 // Throw an exception.
2023 Instrumentation.checkStartActivityResult(
2024 ActivityManager.START_CLASS_NOT_FOUND, intent);
2029 public final Activity startActivityNow(Activity parent, String id,
2030 Intent intent, ActivityInfo activityInfo, IBinder token, Bundle state,
2031 Activity.NonConfigurationInstances lastNonConfigurationInstances) {
2032 ActivityClientRecord r = new ActivityClientRecord();
2039 r.activityInfo = activityInfo;
2040 r.lastNonConfigurationInstances = lastNonConfigurationInstances;
2042 ComponentName compname = intent.getComponent();
2044 if (compname != null) {
2045 name = compname.toShortString();
2047 name = "(Intent " + intent + ").getComponent() returned null";
2049 Slog.v(TAG, "Performing launch: action=" + intent.getAction()
2051 + ", token=" + token);
2053 return performLaunchActivity(r, null);
2056 public final Activity getActivity(IBinder token) {
2057 return mActivities.get(token).activity;
2060 public final void sendActivityResult(
2061 IBinder token, String id, int requestCode,
2062 int resultCode, Intent data) {
2063 if (DEBUG_RESULTS) Slog.v(TAG, "sendActivityResult: id=" + id
2064 + " req=" + requestCode + " res=" + resultCode + " data=" + data);
2065 ArrayList<ResultInfo> list = new ArrayList<ResultInfo>();
2066 list.add(new ResultInfo(id, requestCode, resultCode, data));
2067 mAppThread.scheduleSendResult(token, list);
2070 // if the thread hasn't started yet, we don't have the handler, so just
2071 // save the messages until we're ready.
2072 private void queueOrSendMessage(int what, Object obj) {
2073 queueOrSendMessage(what, obj, 0, 0);
2076 private void queueOrSendMessage(int what, Object obj, int arg1) {
2077 queueOrSendMessage(what, obj, arg1, 0);
2080 private void queueOrSendMessage(int what, Object obj, int arg1, int arg2) {
2081 synchronized (this) {
2082 if (DEBUG_MESSAGES) Slog.v(
2083 TAG, "SCHEDULE " + what + " " + mH.codeToString(what)
2084 + ": " + arg1 + " / " + obj);
2085 Message msg = Message.obtain();
2090 mH.sendMessage(msg);
2094 final void scheduleContextCleanup(ContextImpl context, String who,
2096 ContextCleanupInfo cci = new ContextCleanupInfo();
2097 cci.context = context;
2100 queueOrSendMessage(H.CLEAN_UP_CONTEXT, cci);
2103 private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
2104 // System.out.println("##### [" + System.currentTimeMillis() + "] ActivityThread.performLaunchActivity(" + r + ")");
2106 ActivityInfo aInfo = r.activityInfo;
2107 if (r.packageInfo == null) {
2108 r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
2109 Context.CONTEXT_INCLUDE_CODE);
2112 ComponentName component = r.intent.getComponent();
2113 if (component == null) {
2114 component = r.intent.resolveActivity(
2115 mInitialApplication.getPackageManager());
2116 r.intent.setComponent(component);
2119 if (r.activityInfo.targetActivity != null) {
2120 component = new ComponentName(r.activityInfo.packageName,
2121 r.activityInfo.targetActivity);
2124 Activity activity = null;
2126 java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
2127 activity = mInstrumentation.newActivity(
2128 cl, component.getClassName(), r.intent);
2129 StrictMode.incrementExpectedActivityCount(activity.getClass());
2130 r.intent.setExtrasClassLoader(cl);
2131 if (r.state != null) {
2132 r.state.setClassLoader(cl);
2134 } catch (Exception e) {
2135 if (!mInstrumentation.onException(activity, e)) {
2136 throw new RuntimeException(
2137 "Unable to instantiate activity " + component
2138 + ": " + e.toString(), e);
2143 Application app = r.packageInfo.makeApplication(false, mInstrumentation);
2145 if (localLOGV) Slog.v(TAG, "Performing launch of " + r);
2146 if (localLOGV) Slog.v(
2147 TAG, r + ": app=" + app
2148 + ", appName=" + app.getPackageName()
2149 + ", pkg=" + r.packageInfo.getPackageName()
2150 + ", comp=" + r.intent.getComponent().toShortString()
2151 + ", dir=" + r.packageInfo.getAppDir());
2153 if (activity != null) {
2154 Context appContext = createBaseContextForActivity(r, activity);
2155 CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
2156 Configuration config = new Configuration(mCompatConfiguration);
2157 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "
2158 + r.activityInfo.name + " with config " + config);
2159 activity.attach(appContext, this, getInstrumentation(), r.token,
2160 r.ident, app, r.intent, r.activityInfo, title, r.parent,
2161 r.embeddedID, r.lastNonConfigurationInstances, config);
2163 if (customIntent != null) {
2164 activity.mIntent = customIntent;
2166 r.lastNonConfigurationInstances = null;
2167 activity.mStartedActivity = false;
2168 int theme = r.activityInfo.getThemeResource();
2170 activity.setTheme(theme);
2173 activity.mCalled = false;
2174 mInstrumentation.callActivityOnCreate(activity, r.state);
2175 if (!activity.mCalled) {
2176 throw new SuperNotCalledException(
2177 "Activity " + r.intent.getComponent().toShortString() +
2178 " did not call through to super.onCreate()");
2180 r.activity = activity;
2182 if (!r.activity.mFinished) {
2183 activity.performStart();
2186 if (!r.activity.mFinished) {
2187 if (r.state != null) {
2188 mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
2191 if (!r.activity.mFinished) {
2192 activity.mCalled = false;
2193 mInstrumentation.callActivityOnPostCreate(activity, r.state);
2194 if (!activity.mCalled) {
2195 throw new SuperNotCalledException(
2196 "Activity " + r.intent.getComponent().toShortString() +
2197 " did not call through to super.onPostCreate()");
2203 mActivities.put(r.token, r);
2205 } catch (SuperNotCalledException e) {
2208 } catch (Exception e) {
2209 if (!mInstrumentation.onException(activity, e)) {
2210 throw new RuntimeException(
2211 "Unable to start activity " + component
2212 + ": " + e.toString(), e);
2219 private Context createBaseContextForActivity(ActivityClientRecord r,
2220 final Activity activity) {
2221 ContextImpl appContext = new ContextImpl();
2222 appContext.init(r.packageInfo, r.token, this);
2223 appContext.setOuterContext(activity);
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 Context baseContext = appContext;
2229 String pkgName = SystemProperties.get("debug.second-display.pkg");
2230 if (pkgName != null && !pkgName.isEmpty()
2231 && r.packageInfo.mPackageName.contains(pkgName)) {
2232 DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance();
2233 for (int displayId : dm.getDisplayIds()) {
2234 if (displayId != Display.DEFAULT_DISPLAY) {
2235 Display display = dm.getRealDisplay(displayId);
2236 baseContext = appContext.createDisplayContext(display);
2244 private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
2245 // If we are getting ready to gc after going to the background, well
2246 // we are back active so skip it.
2247 unscheduleGcIdler();
2249 if (r.profileFd != null) {
2250 mProfiler.setProfiler(r.profileFile, r.profileFd);
2251 mProfiler.startProfiling();
2252 mProfiler.autoStopProfiler = r.autoStopProfiler;
2255 // Make sure we are running with the most recent config.
2256 handleConfigurationChanged(null, null);
2258 if (localLOGV) Slog.v(
2259 TAG, "Handling launch of " + r);
2260 Activity a = performLaunchActivity(r, customIntent);
2263 r.createdConfig = new Configuration(mConfiguration);
2264 Bundle oldState = r.state;
2265 handleResumeActivity(r.token, false, r.isForward,
2266 !r.activity.mFinished && !r.startsNotResumed);
2268 if (!r.activity.mFinished && r.startsNotResumed) {
2269 // The activity manager actually wants this one to start out
2270 // paused, because it needs to be visible but isn't in the
2271 // foreground. We accomplish this by going through the
2272 // normal startup (because activities expect to go through
2273 // onResume() the first time they run, before their window
2274 // is displayed), and then pausing it. However, in this case
2275 // we do -not- need to do the full pause cycle (of freezing
2276 // and such) because the activity manager assumes it can just
2277 // retain the current state it has.
2279 r.activity.mCalled = false;
2280 mInstrumentation.callActivityOnPause(r.activity);
2281 // We need to keep around the original state, in case
2282 // we need to be created again. But we only do this
2283 // for pre-Honeycomb apps, which always save their state
2284 // when pausing, so we can not have them save their state
2285 // when restarting from a paused state. For HC and later,
2286 // we want to (and can) let the state be saved as the normal
2287 // part of stopping the activity.
2288 if (r.isPreHoneycomb()) {
2291 if (!r.activity.mCalled) {
2292 throw new SuperNotCalledException(
2293 "Activity " + r.intent.getComponent().toShortString() +
2294 " did not call through to super.onPause()");
2297 } catch (SuperNotCalledException e) {
2300 } catch (Exception e) {
2301 if (!mInstrumentation.onException(r.activity, e)) {
2302 throw new RuntimeException(
2303 "Unable to pause activity "
2304 + r.intent.getComponent().toShortString()
2305 + ": " + e.toString(), e);
2311 // If there was an error, for any reason, tell the activity
2312 // manager to stop us.
2314 ActivityManagerNative.getDefault()
2315 .finishActivity(r.token, Activity.RESULT_CANCELED, null);
2316 } catch (RemoteException ex) {
2322 private void deliverNewIntents(ActivityClientRecord r,
2323 List<Intent> intents) {
2324 final int N = intents.size();
2325 for (int i=0; i<N; i++) {
2326 Intent intent = intents.get(i);
2327 intent.setExtrasClassLoader(r.activity.getClassLoader());
2328 r.activity.mFragments.noteStateNotSaved();
2329 mInstrumentation.callActivityOnNewIntent(r.activity, intent);
2333 public final void performNewIntents(IBinder token,
2334 List<Intent> intents) {
2335 ActivityClientRecord r = mActivities.get(token);
2337 final boolean resumed = !r.paused;
2339 r.activity.mTemporaryPause = true;
2340 mInstrumentation.callActivityOnPause(r.activity);
2342 deliverNewIntents(r, intents);
2344 r.activity.performResume();
2345 r.activity.mTemporaryPause = false;
2350 private void handleNewIntent(NewIntentData data) {
2351 performNewIntents(data.token, data.intents);
2354 public void handleRequestActivityExtras(RequestActivityExtras cmd) {
2355 Bundle data = new Bundle();
2356 ActivityClientRecord r = mActivities.get(cmd.activityToken);
2358 r.activity.getApplication().dispatchOnProvideAssistData(r.activity, data);
2359 r.activity.onProvideAssistData(data);
2361 if (data.isEmpty()) {
2364 IActivityManager mgr = ActivityManagerNative.getDefault();
2366 mgr.reportTopActivityExtras(cmd.requestToken, data);
2367 } catch (RemoteException e) {
2371 private static final ThreadLocal<Intent> sCurrentBroadcastIntent = new ThreadLocal<Intent>();
2374 * Return the Intent that's currently being handled by a
2375 * BroadcastReceiver on this thread, or null if none.
2378 public static Intent getIntentBeingBroadcast() {
2379 return sCurrentBroadcastIntent.get();
2382 private void handleReceiver(ReceiverData data) {
2383 // If we are getting ready to gc after going to the background, well
2384 // we are back active so skip it.
2385 unscheduleGcIdler();
2387 String component = data.intent.getComponent().getClassName();
2389 LoadedApk packageInfo = getPackageInfoNoCheck(
2390 data.info.applicationInfo, data.compatInfo);
2392 IActivityManager mgr = ActivityManagerNative.getDefault();
2394 BroadcastReceiver receiver;
2396 java.lang.ClassLoader cl = packageInfo.getClassLoader();
2397 data.intent.setExtrasClassLoader(cl);
2398 data.setExtrasClassLoader(cl);
2399 receiver = (BroadcastReceiver)cl.loadClass(component).newInstance();
2400 } catch (Exception e) {
2401 if (DEBUG_BROADCAST) Slog.i(TAG,
2402 "Finishing failed broadcast to " + data.intent.getComponent());
2403 data.sendFinished(mgr);
2404 throw new RuntimeException(
2405 "Unable to instantiate receiver " + component
2406 + ": " + e.toString(), e);
2410 Application app = packageInfo.makeApplication(false, mInstrumentation);
2412 if (localLOGV) Slog.v(
2413 TAG, "Performing receive of " + data.intent
2415 + ", appName=" + app.getPackageName()
2416 + ", pkg=" + packageInfo.getPackageName()
2417 + ", comp=" + data.intent.getComponent().toShortString()
2418 + ", dir=" + packageInfo.getAppDir());
2420 ContextImpl context = (ContextImpl)app.getBaseContext();
2421 sCurrentBroadcastIntent.set(data.intent);
2422 receiver.setPendingResult(data);
2423 receiver.onReceive(context.getReceiverRestrictedContext(),
2425 } catch (Exception e) {
2426 if (DEBUG_BROADCAST) Slog.i(TAG,
2427 "Finishing failed broadcast to " + data.intent.getComponent());
2428 data.sendFinished(mgr);
2429 if (!mInstrumentation.onException(receiver, e)) {
2430 throw new RuntimeException(
2431 "Unable to start receiver " + component
2432 + ": " + e.toString(), e);
2435 sCurrentBroadcastIntent.set(null);
2438 if (receiver.getPendingResult() != null) {
2443 // Instantiate a BackupAgent and tell it that it's alive
2444 private void handleCreateBackupAgent(CreateBackupAgentData data) {
2445 if (DEBUG_BACKUP) Slog.v(TAG, "handleCreateBackupAgent: " + data);
2447 // Sanity check the requested target package's uid against ours
2449 PackageInfo requestedPackage = getPackageManager().getPackageInfo(
2450 data.appInfo.packageName, 0, UserHandle.myUserId());
2451 if (requestedPackage.applicationInfo.uid != Process.myUid()) {
2452 Slog.w(TAG, "Asked to instantiate non-matching package "
2453 + data.appInfo.packageName);
2456 } catch (RemoteException e) {
2457 Slog.e(TAG, "Can't reach package manager", e);
2461 // no longer idle; we have backup work to do
2462 unscheduleGcIdler();
2464 // instantiate the BackupAgent class named in the manifest
2465 LoadedApk packageInfo = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
2466 String packageName = packageInfo.mPackageName;
2467 if (packageName == null) {
2468 Slog.d(TAG, "Asked to create backup agent for nonexistent package");
2472 if (mBackupAgents.get(packageName) != null) {
2473 Slog.d(TAG, "BackupAgent " + " for " + packageName
2474 + " already exists");
2478 BackupAgent agent = null;
2479 String classname = data.appInfo.backupAgentName;
2481 // full backup operation but no app-supplied agent? use the default implementation
2482 if (classname == null && (data.backupMode == IApplicationThread.BACKUP_MODE_FULL
2483 || data.backupMode == IApplicationThread.BACKUP_MODE_RESTORE_FULL)) {
2484 classname = "android.app.backup.FullBackupAgent";
2488 IBinder binder = null;
2490 if (DEBUG_BACKUP) Slog.v(TAG, "Initializing agent class " + classname);
2492 java.lang.ClassLoader cl = packageInfo.getClassLoader();
2493 agent = (BackupAgent) cl.loadClass(classname).newInstance();
2495 // set up the agent's context
2496 ContextImpl context = new ContextImpl();
2497 context.init(packageInfo, null, this);
2498 context.setOuterContext(agent);
2499 agent.attach(context);
2502 binder = agent.onBind();
2503 mBackupAgents.put(packageName, agent);
2504 } catch (Exception e) {
2505 // If this is during restore, fail silently; otherwise go
2506 // ahead and let the user see the crash.
2507 Slog.e(TAG, "Agent threw during creation: " + e);
2508 if (data.backupMode != IApplicationThread.BACKUP_MODE_RESTORE
2509 && data.backupMode != IApplicationThread.BACKUP_MODE_RESTORE_FULL) {
2512 // falling through with 'binder' still null
2515 // tell the OS that we're live now
2517 ActivityManagerNative.getDefault().backupAgentCreated(packageName, binder);
2518 } catch (RemoteException e) {
2521 } catch (Exception e) {
2522 throw new RuntimeException("Unable to create BackupAgent "
2523 + classname + ": " + e.toString(), e);
2527 // Tear down a BackupAgent
2528 private void handleDestroyBackupAgent(CreateBackupAgentData data) {
2529 if (DEBUG_BACKUP) Slog.v(TAG, "handleDestroyBackupAgent: " + data);
2531 LoadedApk packageInfo = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
2532 String packageName = packageInfo.mPackageName;
2533 BackupAgent agent = mBackupAgents.get(packageName);
2534 if (agent != null) {
2537 } catch (Exception e) {
2538 Slog.w(TAG, "Exception thrown in onDestroy by backup agent of " + data.appInfo);
2539 e.printStackTrace();
2541 mBackupAgents.remove(packageName);
2543 Slog.w(TAG, "Attempt to destroy unknown backup agent " + data);
2547 private void handleCreateService(CreateServiceData data) {
2548 // If we are getting ready to gc after going to the background, well
2549 // we are back active so skip it.
2550 unscheduleGcIdler();
2552 LoadedApk packageInfo = getPackageInfoNoCheck(
2553 data.info.applicationInfo, data.compatInfo);
2554 Service service = null;
2556 java.lang.ClassLoader cl = packageInfo.getClassLoader();
2557 service = (Service) cl.loadClass(data.info.name).newInstance();
2558 } catch (Exception e) {
2559 if (!mInstrumentation.onException(service, e)) {
2560 throw new RuntimeException(
2561 "Unable to instantiate service " + data.info.name
2562 + ": " + e.toString(), e);
2567 if (localLOGV) Slog.v(TAG, "Creating service " + data.info.name);
2569 ContextImpl context = new ContextImpl();
2570 context.init(packageInfo, null, this);
2572 Application app = packageInfo.makeApplication(false, mInstrumentation);
2573 context.setOuterContext(service);
2574 service.attach(context, this, data.info.name, data.token, app,
2575 ActivityManagerNative.getDefault());
2577 mServices.put(data.token, service);
2579 ActivityManagerNative.getDefault().serviceDoneExecuting(
2580 data.token, 0, 0, 0);
2581 } catch (RemoteException e) {
2584 } catch (Exception e) {
2585 if (!mInstrumentation.onException(service, e)) {
2586 throw new RuntimeException(
2587 "Unable to create service " + data.info.name
2588 + ": " + e.toString(), e);
2593 private void handleBindService(BindServiceData data) {
2594 Service s = mServices.get(data.token);
2596 Slog.v(TAG, "handleBindService s=" + s + " rebind=" + data.rebind);
2599 data.intent.setExtrasClassLoader(s.getClassLoader());
2602 IBinder binder = s.onBind(data.intent);
2603 ActivityManagerNative.getDefault().publishService(
2604 data.token, data.intent, binder);
2606 s.onRebind(data.intent);
2607 ActivityManagerNative.getDefault().serviceDoneExecuting(
2608 data.token, 0, 0, 0);
2611 } catch (RemoteException ex) {
2613 } catch (Exception e) {
2614 if (!mInstrumentation.onException(s, e)) {
2615 throw new RuntimeException(
2616 "Unable to bind to service " + s
2617 + " with " + data.intent + ": " + e.toString(), e);
2623 private void handleUnbindService(BindServiceData data) {
2624 Service s = mServices.get(data.token);
2627 data.intent.setExtrasClassLoader(s.getClassLoader());
2628 boolean doRebind = s.onUnbind(data.intent);
2631 ActivityManagerNative.getDefault().unbindFinished(
2632 data.token, data.intent, doRebind);
2634 ActivityManagerNative.getDefault().serviceDoneExecuting(
2635 data.token, 0, 0, 0);
2637 } catch (RemoteException ex) {
2639 } catch (Exception e) {
2640 if (!mInstrumentation.onException(s, e)) {
2641 throw new RuntimeException(
2642 "Unable to unbind to service " + s
2643 + " with " + data.intent + ": " + e.toString(), e);
2649 private void handleDumpService(DumpComponentInfo info) {
2650 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
2652 Service s = mServices.get(info.token);
2654 PrintWriter pw = new PrintWriter(new FileOutputStream(info.fd.getFileDescriptor()));
2655 s.dump(info.fd.getFileDescriptor(), pw, info.args);
2659 IoUtils.closeQuietly(info.fd);
2660 StrictMode.setThreadPolicy(oldPolicy);
2664 private void handleDumpActivity(DumpComponentInfo info) {
2665 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
2667 ActivityClientRecord r = mActivities.get(info.token);
2668 if (r != null && r.activity != null) {
2669 PrintWriter pw = new PrintWriter(new FileOutputStream(info.fd.getFileDescriptor()));
2670 r.activity.dump(info.prefix, info.fd.getFileDescriptor(), pw, info.args);
2674 IoUtils.closeQuietly(info.fd);
2675 StrictMode.setThreadPolicy(oldPolicy);
2679 private void handleDumpProvider(DumpComponentInfo info) {
2680 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
2682 ProviderClientRecord r = mLocalProviders.get(info.token);
2683 if (r != null && r.mLocalProvider != null) {
2684 PrintWriter pw = new PrintWriter(new FileOutputStream(info.fd.getFileDescriptor()));
2685 r.mLocalProvider.dump(info.fd.getFileDescriptor(), pw, info.args);
2689 IoUtils.closeQuietly(info.fd);
2690 StrictMode.setThreadPolicy(oldPolicy);
2694 private void handleServiceArgs(ServiceArgsData data) {
2695 Service s = mServices.get(data.token);
2698 if (data.args != null) {
2699 data.args.setExtrasClassLoader(s.getClassLoader());
2702 if (!data.taskRemoved) {
2703 res = s.onStartCommand(data.args, data.flags, data.startId);
2705 s.onTaskRemoved(data.args);
2706 res = Service.START_TASK_REMOVED_COMPLETE;
2709 QueuedWork.waitToFinish();
2712 ActivityManagerNative.getDefault().serviceDoneExecuting(
2713 data.token, 1, data.startId, res);
2714 } catch (RemoteException e) {
2718 } catch (Exception e) {
2719 if (!mInstrumentation.onException(s, e)) {
2720 throw new RuntimeException(
2721 "Unable to start service " + s
2722 + " with " + data.args + ": " + e.toString(), e);
2728 private void handleStopService(IBinder token) {
2729 Service s = mServices.remove(token);
2732 if (localLOGV) Slog.v(TAG, "Destroying service " + s);
2734 Context context = s.getBaseContext();
2735 if (context instanceof ContextImpl) {
2736 final String who = s.getClassName();
2737 ((ContextImpl) context).scheduleFinalCleanup(who, "Service");
2740 QueuedWork.waitToFinish();
2743 ActivityManagerNative.getDefault().serviceDoneExecuting(
2745 } catch (RemoteException e) {
2748 } catch (Exception e) {
2749 if (!mInstrumentation.onException(s, e)) {
2750 throw new RuntimeException(
2751 "Unable to stop service " + s
2752 + ": " + e.toString(), e);
2756 //Slog.i(TAG, "Running services: " + mServices);
2759 public final ActivityClientRecord performResumeActivity(IBinder token,
2760 boolean clearHide) {
2761 ActivityClientRecord r = mActivities.get(token);
2762 if (localLOGV) Slog.v(TAG, "Performing resume of " + r
2763 + " finished=" + r.activity.mFinished);
2764 if (r != null && !r.activity.mFinished) {
2766 r.hideForNow = false;
2767 r.activity.mStartedActivity = false;
2770 r.activity.mFragments.noteStateNotSaved();
2771 if (r.pendingIntents != null) {
2772 deliverNewIntents(r, r.pendingIntents);
2773 r.pendingIntents = null;
2775 if (r.pendingResults != null) {
2776 deliverResults(r, r.pendingResults);
2777 r.pendingResults = null;
2779 r.activity.performResume();
2781 EventLog.writeEvent(LOG_ON_RESUME_CALLED,
2782 UserHandle.myUserId(), r.activity.getComponentName().getClassName());
2787 } catch (Exception e) {
2788 if (!mInstrumentation.onException(r.activity, e)) {
2789 throw new RuntimeException(
2790 "Unable to resume activity "
2791 + r.intent.getComponent().toShortString()
2792 + ": " + e.toString(), e);
2799 static final void cleanUpPendingRemoveWindows(ActivityClientRecord r) {
2800 if (r.mPendingRemoveWindow != null) {
2801 r.mPendingRemoveWindowManager.removeViewImmediate(r.mPendingRemoveWindow);
2802 IBinder wtoken = r.mPendingRemoveWindow.getWindowToken();
2803 if (wtoken != null) {
2804 WindowManagerGlobal.getInstance().closeAll(wtoken,
2805 r.activity.getClass().getName(), "Activity");
2808 r.mPendingRemoveWindow = null;
2809 r.mPendingRemoveWindowManager = null;
2812 final void handleResumeActivity(IBinder token, boolean clearHide, boolean isForward,
2813 boolean reallyResume) {
2814 // If we are getting ready to gc after going to the background, well
2815 // we are back active so skip it.
2816 unscheduleGcIdler();
2818 ActivityClientRecord r = performResumeActivity(token, clearHide);
2821 final Activity a = r.activity;
2823 if (localLOGV) Slog.v(
2824 TAG, "Resume " + r + " started activity: " +
2825 a.mStartedActivity + ", hideForNow: " + r.hideForNow
2826 + ", finished: " + a.mFinished);
2828 final int forwardBit = isForward ?
2829 WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION : 0;
2831 // If the window hasn't yet been added to the window manager,
2832 // and this guy didn't finish itself or start another activity,
2833 // then go ahead and add the window.
2834 boolean willBeVisible = !a.mStartedActivity;
2835 if (!willBeVisible) {
2837 willBeVisible = ActivityManagerNative.getDefault().willActivityBeVisible(
2838 a.getActivityToken());
2839 } catch (RemoteException e) {
2842 if (r.window == null && !a.mFinished && willBeVisible) {
2843 r.window = r.activity.getWindow();
2844 View decor = r.window.getDecorView();
2845 decor.setVisibility(View.INVISIBLE);
2846 ViewManager wm = a.getWindowManager();
2847 WindowManager.LayoutParams l = r.window.getAttributes();
2849 l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
2850 l.softInputMode |= forwardBit;
2851 if (a.mVisibleFromClient) {
2852 a.mWindowAdded = true;
2853 wm.addView(decor, l);
2856 // If the window has already been added, but during resume
2857 // we started another activity, then don't yet make the
2859 } else if (!willBeVisible) {
2860 if (localLOGV) Slog.v(
2861 TAG, "Launch " + r + " mStartedActivity set");
2862 r.hideForNow = true;
2865 // Get rid of anything left hanging around.
2866 cleanUpPendingRemoveWindows(r);
2868 // The window is now visible if it has been added, we are not
2869 // simply finishing, and we are not starting another activity.
2870 if (!r.activity.mFinished && willBeVisible
2871 && r.activity.mDecor != null && !r.hideForNow) {
2872 if (r.newConfig != null) {
2873 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Resuming activity "
2874 + r.activityInfo.name + " with newConfig " + r.newConfig);
2875 performConfigurationChanged(r.activity, r.newConfig);
2876 freeTextLayoutCachesIfNeeded(r.activity.mCurrentConfig.diff(r.newConfig));
2879 if (localLOGV) Slog.v(TAG, "Resuming " + r + " with isForward="
2881 WindowManager.LayoutParams l = r.window.getAttributes();
2882 if ((l.softInputMode
2883 & WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION)
2885 l.softInputMode = (l.softInputMode
2886 & (~WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION))
2888 if (r.activity.mVisibleFromClient) {
2889 ViewManager wm = a.getWindowManager();
2890 View decor = r.window.getDecorView();
2891 wm.updateViewLayout(decor, l);
2894 r.activity.mVisibleFromServer = true;
2895 mNumVisibleActivities++;
2896 if (r.activity.mVisibleFromClient) {
2897 r.activity.makeVisible();
2901 if (!r.onlyLocalRequest) {
2902 r.nextIdle = mNewActivities;
2904 if (localLOGV) Slog.v(
2905 TAG, "Scheduling idle handler for " + r);
2906 Looper.myQueue().addIdleHandler(new Idler());
2908 r.onlyLocalRequest = false;
2910 // Tell the activity manager we have resumed.
2913 ActivityManagerNative.getDefault().activityResumed(token);
2914 } catch (RemoteException ex) {
2919 // If an exception was thrown when trying to resume, then
2920 // just end this activity.
2922 ActivityManagerNative.getDefault()
2923 .finishActivity(token, Activity.RESULT_CANCELED, null);
2924 } catch (RemoteException ex) {
2929 private int mThumbnailWidth = -1;
2930 private int mThumbnailHeight = -1;
2931 private Bitmap mAvailThumbnailBitmap = null;
2932 private Canvas mThumbnailCanvas = null;
2934 private Bitmap createThumbnailBitmap(ActivityClientRecord r) {
2935 Bitmap thumbnail = mAvailThumbnailBitmap;
2937 if (thumbnail == null) {
2938 int w = mThumbnailWidth;
2941 Resources res = r.activity.getResources();
2942 mThumbnailHeight = h =
2943 res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
2945 mThumbnailWidth = w =
2946 res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
2948 h = mThumbnailHeight;
2951 // On platforms where we don't want thumbnails, set dims to (0,0)
2952 if ((w > 0) && (h > 0)) {
2953 thumbnail = Bitmap.createBitmap(r.activity.getResources().getDisplayMetrics(),
2954 w, h, THUMBNAIL_FORMAT);
2955 thumbnail.eraseColor(0);
2959 if (thumbnail != null) {
2960 Canvas cv = mThumbnailCanvas;
2962 mThumbnailCanvas = cv = new Canvas();
2965 cv.setBitmap(thumbnail);
2966 if (!r.activity.onCreateThumbnail(thumbnail, cv)) {
2967 mAvailThumbnailBitmap = thumbnail;
2973 } catch (Exception e) {
2974 if (!mInstrumentation.onException(r.activity, e)) {
2975 throw new RuntimeException(
2976 "Unable to create thumbnail of "
2977 + r.intent.getComponent().toShortString()
2978 + ": " + e.toString(), e);
2986 private void handlePauseActivity(IBinder token, boolean finished,
2987 boolean userLeaving, int configChanges) {
2988 ActivityClientRecord r = mActivities.get(token);
2990 //Slog.v(TAG, "userLeaving=" + userLeaving + " handling pause of " + r);
2992 performUserLeavingActivity(r);
2995 r.activity.mConfigChangeFlags |= configChanges;
2996 performPauseActivity(token, finished, r.isPreHoneycomb());
2998 // Make sure any pending writes are now committed.
2999 if (r.isPreHoneycomb()) {
3000 QueuedWork.waitToFinish();
3003 // Tell the activity manager we have paused.
3005 ActivityManagerNative.getDefault().activityPaused(token);
3006 } catch (RemoteException ex) {
3011 final void performUserLeavingActivity(ActivityClientRecord r) {
3012 mInstrumentation.callActivityOnUserLeaving(r.activity);
3015 final Bundle performPauseActivity(IBinder token, boolean finished,
3016 boolean saveState) {
3017 ActivityClientRecord r = mActivities.get(token);
3018 return r != null ? performPauseActivity(r, finished, saveState) : null;
3021 final Bundle performPauseActivity(ActivityClientRecord r, boolean finished,
3022 boolean saveState) {
3024 if (r.activity.mFinished) {
3025 // If we are finishing, we won't call onResume() in certain cases.
3026 // So here we likewise don't want to call onPause() if the activity
3030 RuntimeException e = new RuntimeException(
3031 "Performing pause of activity that is not resumed: "
3032 + r.intent.getComponent().toShortString());
3033 Slog.e(TAG, e.getMessage(), e);
3035 Bundle state = null;
3037 r.activity.mFinished = true;
3040 // Next have the activity save its current state and managed dialogs...
3041 if (!r.activity.mFinished && saveState) {
3042 state = new Bundle();
3043 state.setAllowFds(false);
3044 mInstrumentation.callActivityOnSaveInstanceState(r.activity, state);
3048 r.activity.mCalled = false;
3049 mInstrumentation.callActivityOnPause(r.activity);
3050 EventLog.writeEvent(LOG_ON_PAUSE_CALLED, UserHandle.myUserId(),
3051 r.activity.getComponentName().getClassName());
3052 if (!r.activity.mCalled) {
3053 throw new SuperNotCalledException(
3054 "Activity " + r.intent.getComponent().toShortString() +
3055 " did not call through to super.onPause()");
3058 } catch (SuperNotCalledException e) {
3061 } catch (Exception e) {
3062 if (!mInstrumentation.onException(r.activity, e)) {
3063 throw new RuntimeException(
3064 "Unable to pause activity "
3065 + r.intent.getComponent().toShortString()
3066 + ": " + e.toString(), e);
3071 // Notify any outstanding on paused listeners
3072 ArrayList<OnActivityPausedListener> listeners;
3073 synchronized (mOnPauseListeners) {
3074 listeners = mOnPauseListeners.remove(r.activity);
3076 int size = (listeners != null ? listeners.size() : 0);
3077 for (int i = 0; i < size; i++) {
3078 listeners.get(i).onPaused(r.activity);
3084 final void performStopActivity(IBinder token, boolean saveState) {
3085 ActivityClientRecord r = mActivities.get(token);
3086 performStopActivityInner(r, null, false, saveState);
3089 private static class StopInfo implements Runnable {
3090 ActivityClientRecord activity;
3093 CharSequence description;
3095 @Override public void run() {
3096 // Tell activity manager we have been stopped.
3098 if (DEBUG_MEMORY_TRIM) Slog.v(TAG, "Reporting activity stopped: " + activity);
3099 ActivityManagerNative.getDefault().activityStopped(
3100 activity.token, state, thumbnail, description);
3101 } catch (RemoteException ex) {
3106 private static final class ProviderRefCount {
3107 public final IActivityManager.ContentProviderHolder holder;
3108 public final ProviderClientRecord client;
3109 public int stableCount;
3110 public int unstableCount;
3112 // When this is set, the stable and unstable ref counts are 0 and
3113 // we have a pending operation scheduled to remove the ref count
3114 // from the activity manager. On the activity manager we are still
3115 // holding an unstable ref, though it is not reflected in the counts
3117 public boolean removePending;
3119 ProviderRefCount(IActivityManager.ContentProviderHolder inHolder,
3120 ProviderClientRecord inClient, int sCount, int uCount) {
3123 stableCount = sCount;
3124 unstableCount = uCount;
3129 * Core implementation of stopping an activity. Note this is a little
3130 * tricky because the server's meaning of stop is slightly different
3131 * than our client -- for the server, stop means to save state and give
3132 * it the result when it is done, but the window may still be visible.
3133 * For the client, we want to call onStop()/onStart() to indicate when
3134 * the activity's UI visibillity changes.
3136 private void performStopActivityInner(ActivityClientRecord r,
3137 StopInfo info, boolean keepShown, boolean saveState) {
3138 if (localLOGV) Slog.v(TAG, "Performing stop of " + r);
3139 Bundle state = null;
3141 if (!keepShown && r.stopped) {
3142 if (r.activity.mFinished) {
3143 // If we are finishing, we won't call onResume() in certain
3144 // cases. So here we likewise don't want to call onStop()
3145 // if the activity isn't resumed.
3148 RuntimeException e = new RuntimeException(
3149 "Performing stop of activity that is not resumed: "
3150 + r.intent.getComponent().toShortString());
3151 Slog.e(TAG, e.getMessage(), e);
3156 // First create a thumbnail for the activity...
3157 // For now, don't create the thumbnail here; we are
3158 // doing that by doing a screen snapshot.
3159 info.thumbnail = null; //createThumbnailBitmap(r);
3160 info.description = r.activity.onCreateDescription();
3161 } catch (Exception e) {
3162 if (!mInstrumentation.onException(r.activity, e)) {
3163 throw new RuntimeException(
3164 "Unable to save state of activity "
3165 + r.intent.getComponent().toShortString()
3166 + ": " + e.toString(), e);
3171 // Next have the activity save its current state and managed dialogs...
3172 if (!r.activity.mFinished && saveState) {
3173 if (r.state == null) {
3174 state = new Bundle();
3175 state.setAllowFds(false);
3176 mInstrumentation.callActivityOnSaveInstanceState(r.activity, state);
3186 r.activity.performStop();
3187 } catch (Exception e) {
3188 if (!mInstrumentation.onException(r.activity, e)) {
3189 throw new RuntimeException(
3190 "Unable to stop activity "
3191 + r.intent.getComponent().toShortString()
3192 + ": " + e.toString(), e);
3202 private void updateVisibility(ActivityClientRecord r, boolean show) {
3203 View v = r.activity.mDecor;
3206 if (!r.activity.mVisibleFromServer) {
3207 r.activity.mVisibleFromServer = true;
3208 mNumVisibleActivities++;
3209 if (r.activity.mVisibleFromClient) {
3210 r.activity.makeVisible();
3213 if (r.newConfig != null) {
3214 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Updating activity vis "
3215 + r.activityInfo.name + " with new config " + r.newConfig);
3216 performConfigurationChanged(r.activity, r.newConfig);
3217 freeTextLayoutCachesIfNeeded(r.activity.mCurrentConfig.diff(r.newConfig));
3221 if (r.activity.mVisibleFromServer) {
3222 r.activity.mVisibleFromServer = false;
3223 mNumVisibleActivities--;
3224 v.setVisibility(View.INVISIBLE);
3230 private void handleStopActivity(IBinder token, boolean show, int configChanges) {
3231 ActivityClientRecord r = mActivities.get(token);
3232 r.activity.mConfigChangeFlags |= configChanges;
3234 StopInfo info = new StopInfo();
3235 performStopActivityInner(r, info, show, true);
3237 if (localLOGV) Slog.v(
3238 TAG, "Finishing stop of " + r + ": show=" + show
3239 + " win=" + r.window);
3241 updateVisibility(r, show);
3243 // Make sure any pending writes are now committed.
3244 if (!r.isPreHoneycomb()) {
3245 QueuedWork.waitToFinish();
3248 // Schedule the call to tell the activity manager we have
3249 // stopped. We don't do this immediately, because we want to
3250 // have a chance for any other pending work (in particular memory
3251 // trim requests) to complete before you tell the activity
3252 // manager to proceed and allow us to go fully into the background.
3254 info.state = r.state;
3258 final void performRestartActivity(IBinder token) {
3259 ActivityClientRecord r = mActivities.get(token);
3261 r.activity.performRestart();
3266 private void handleWindowVisibility(IBinder token, boolean show) {
3267 ActivityClientRecord r = mActivities.get(token);
3270 Log.w(TAG, "handleWindowVisibility: no activity for token " + token);
3274 if (!show && !r.stopped) {
3275 performStopActivityInner(r, null, show, false);
3276 } else if (show && r.stopped) {
3277 // If we are getting ready to gc after going to the background, well
3278 // we are back active so skip it.
3279 unscheduleGcIdler();
3281 r.activity.performRestart();
3284 if (r.activity.mDecor != null) {
3286 TAG, "Handle window " + r + " visibility: " + show);
3287 updateVisibility(r, show);
3291 private void handleSleeping(IBinder token, boolean sleeping) {
3292 ActivityClientRecord r = mActivities.get(token);
3295 Log.w(TAG, "handleSleeping: no activity for token " + token);
3300 if (!r.stopped && !r.isPreHoneycomb()) {
3303 r.activity.performStop();
3304 } catch (Exception e) {
3305 if (!mInstrumentation.onException(r.activity, e)) {
3306 throw new RuntimeException(
3307 "Unable to stop activity "
3308 + r.intent.getComponent().toShortString()
3309 + ": " + e.toString(), e);
3315 // Make sure any pending writes are now committed.
3316 if (!r.isPreHoneycomb()) {
3317 QueuedWork.waitToFinish();
3320 // Tell activity manager we slept.
3322 ActivityManagerNative.getDefault().activitySlept(r.token);
3323 } catch (RemoteException ex) {
3326 if (r.stopped && r.activity.mVisibleFromServer) {
3327 r.activity.performRestart();
3333 private void handleSetCoreSettings(Bundle coreSettings) {
3334 synchronized (mPackages) {
3335 mCoreSettings = coreSettings;
3339 private void handleUpdatePackageCompatibilityInfo(UpdateCompatibilityData data) {
3340 LoadedApk apk = peekPackageInfo(data.pkg, false);
3342 apk.mCompatibilityInfo.set(data.info);
3344 apk = peekPackageInfo(data.pkg, true);
3346 apk.mCompatibilityInfo.set(data.info);
3348 handleConfigurationChanged(mConfiguration, data.info);
3349 WindowManagerGlobal.getInstance().reportNewConfiguration(mConfiguration);
3352 private void deliverResults(ActivityClientRecord r, List<ResultInfo> results) {
3353 final int N = results.size();
3354 for (int i=0; i<N; i++) {
3355 ResultInfo ri = results.get(i);
3357 if (ri.mData != null) {
3358 ri.mData.setExtrasClassLoader(r.activity.getClassLoader());
3360 if (DEBUG_RESULTS) Slog.v(TAG,
3361 "Delivering result to activity " + r + " : " + ri);
3362 r.activity.dispatchActivityResult(ri.mResultWho,
3363 ri.mRequestCode, ri.mResultCode, ri.mData);
3364 } catch (Exception e) {
3365 if (!mInstrumentation.onException(r.activity, e)) {
3366 throw new RuntimeException(
3367 "Failure delivering result " + ri + " to activity "
3368 + r.intent.getComponent().toShortString()
3369 + ": " + e.toString(), e);
3375 private void handleSendResult(ResultData res) {
3376 ActivityClientRecord r = mActivities.get(res.token);
3377 if (DEBUG_RESULTS) Slog.v(TAG, "Handling send result to " + r);
3379 final boolean resumed = !r.paused;
3380 if (!r.activity.mFinished && r.activity.mDecor != null
3381 && r.hideForNow && resumed) {
3382 // We had hidden the activity because it started another
3383 // one... we have gotten a result back and we are not
3384 // paused, so make sure our window is visible.
3385 updateVisibility(r, true);
3390 r.activity.mCalled = false;
3391 r.activity.mTemporaryPause = true;
3392 mInstrumentation.callActivityOnPause(r.activity);
3393 if (!r.activity.mCalled) {
3394 throw new SuperNotCalledException(
3395 "Activity " + r.intent.getComponent().toShortString()
3396 + " did not call through to super.onPause()");
3398 } catch (SuperNotCalledException e) {
3400 } catch (Exception e) {
3401 if (!mInstrumentation.onException(r.activity, e)) {
3402 throw new RuntimeException(
3403 "Unable to pause activity "
3404 + r.intent.getComponent().toShortString()
3405 + ": " + e.toString(), e);
3409 deliverResults(r, res.results);
3411 r.activity.performResume();
3412 r.activity.mTemporaryPause = false;
3417 public final ActivityClientRecord performDestroyActivity(IBinder token, boolean finishing) {
3418 return performDestroyActivity(token, finishing, 0, false);
3421 private ActivityClientRecord performDestroyActivity(IBinder token, boolean finishing,
3422 int configChanges, boolean getNonConfigInstance) {
3423 ActivityClientRecord r = mActivities.get(token);
3424 Class activityClass = null;
3425 if (localLOGV) Slog.v(TAG, "Performing finish of " + r);
3427 activityClass = r.activity.getClass();
3428 r.activity.mConfigChangeFlags |= configChanges;
3430 r.activity.mFinished = true;
3434 r.activity.mCalled = false;
3435 mInstrumentation.callActivityOnPause(r.activity);
3436 EventLog.writeEvent(LOG_ON_PAUSE_CALLED, UserHandle.myUserId(),
3437 r.activity.getComponentName().getClassName());
3438 if (!r.activity.mCalled) {
3439 throw new SuperNotCalledException(
3440 "Activity " + safeToComponentShortString(r.intent)
3441 + " did not call through to super.onPause()");
3443 } catch (SuperNotCalledException e) {
3445 } catch (Exception e) {
3446 if (!mInstrumentation.onException(r.activity, e)) {
3447 throw new RuntimeException(
3448 "Unable to pause activity "
3449 + safeToComponentShortString(r.intent)
3450 + ": " + e.toString(), e);
3457 r.activity.performStop();
3458 } catch (SuperNotCalledException e) {
3460 } catch (Exception e) {
3461 if (!mInstrumentation.onException(r.activity, e)) {
3462 throw new RuntimeException(
3463 "Unable to stop activity "
3464 + safeToComponentShortString(r.intent)
3465 + ": " + e.toString(), e);
3470 if (getNonConfigInstance) {
3472 r.lastNonConfigurationInstances
3473 = r.activity.retainNonConfigurationInstances();
3474 } catch (Exception e) {
3475 if (!mInstrumentation.onException(r.activity, e)) {
3476 throw new RuntimeException(
3477 "Unable to retain activity "
3478 + r.intent.getComponent().toShortString()
3479 + ": " + e.toString(), e);
3484 r.activity.mCalled = false;
3485 mInstrumentation.callActivityOnDestroy(r.activity);
3486 if (!r.activity.mCalled) {
3487 throw new SuperNotCalledException(
3488 "Activity " + safeToComponentShortString(r.intent) +
3489 " did not call through to super.onDestroy()");
3491 if (r.window != null) {
3492 r.window.closeAllPanels();
3494 } catch (SuperNotCalledException e) {
3496 } catch (Exception e) {
3497 if (!mInstrumentation.onException(r.activity, e)) {
3498 throw new RuntimeException(
3499 "Unable to destroy activity " + safeToComponentShortString(r.intent)
3500 + ": " + e.toString(), e);
3504 mActivities.remove(token);
3505 StrictMode.decrementExpectedActivityCount(activityClass);
3509 private static String safeToComponentShortString(Intent intent) {
3510 ComponentName component = intent.getComponent();
3511 return component == null ? "[Unknown]" : component.toShortString();
3514 private void handleDestroyActivity(IBinder token, boolean finishing,
3515 int configChanges, boolean getNonConfigInstance) {
3516 ActivityClientRecord r = performDestroyActivity(token, finishing,
3517 configChanges, getNonConfigInstance);
3519 cleanUpPendingRemoveWindows(r);
3520 WindowManager wm = r.activity.getWindowManager();
3521 View v = r.activity.mDecor;
3523 if (r.activity.mVisibleFromServer) {
3524 mNumVisibleActivities--;
3526 IBinder wtoken = v.getWindowToken();
3527 if (r.activity.mWindowAdded) {
3528 if (r.onlyLocalRequest) {
3529 // Hold off on removing this until the new activity's
3530 // window is being added.
3531 r.mPendingRemoveWindow = v;
3532 r.mPendingRemoveWindowManager = wm;
3534 wm.removeViewImmediate(v);
3537 if (wtoken != null && r.mPendingRemoveWindow == null) {
3538 WindowManagerGlobal.getInstance().closeAll(wtoken,
3539 r.activity.getClass().getName(), "Activity");
3541 r.activity.mDecor = null;
3543 if (r.mPendingRemoveWindow == null) {
3544 // If we are delaying the removal of the activity window, then
3545 // we can't clean up all windows here. Note that we can't do
3546 // so later either, which means any windows that aren't closed
3547 // by the app will leak. Well we try to warning them a lot
3548 // about leaking windows, because that is a bug, so if they are
3549 // using this recreate facility then they get to live with leaks.
3550 WindowManagerGlobal.getInstance().closeAll(token,
3551 r.activity.getClass().getName(), "Activity");
3554 // Mocked out contexts won't be participating in the normal
3555 // process lifecycle, but if we're running with a proper
3556 // ApplicationContext we need to have it tear down things
3558 Context c = r.activity.getBaseContext();
3559 if (c instanceof ContextImpl) {
3560 ((ContextImpl) c).scheduleFinalCleanup(
3561 r.activity.getClass().getName(), "Activity");
3566 ActivityManagerNative.getDefault().activityDestroyed(token);
3567 } catch (RemoteException ex) {
3568 // If the system process has died, it's game over for everyone.
3573 public final void requestRelaunchActivity(IBinder token,
3574 List<ResultInfo> pendingResults, List<Intent> pendingNewIntents,
3575 int configChanges, boolean notResumed, Configuration config,
3576 boolean fromServer) {
3577 ActivityClientRecord target = null;
3579 synchronized (mPackages) {
3580 for (int i=0; i<mRelaunchingActivities.size(); i++) {
3581 ActivityClientRecord r = mRelaunchingActivities.get(i);
3582 if (r.token == token) {
3584 if (pendingResults != null) {
3585 if (r.pendingResults != null) {
3586 r.pendingResults.addAll(pendingResults);
3588 r.pendingResults = pendingResults;
3591 if (pendingNewIntents != null) {
3592 if (r.pendingIntents != null) {
3593 r.pendingIntents.addAll(pendingNewIntents);
3595 r.pendingIntents = pendingNewIntents;
3602 if (target == null) {
3603 target = new ActivityClientRecord();
3604 target.token = token;
3605 target.pendingResults = pendingResults;
3606 target.pendingIntents = pendingNewIntents;
3608 ActivityClientRecord existing = mActivities.get(token);
3609 if (existing != null) {
3610 target.startsNotResumed = existing.paused;
3612 target.onlyLocalRequest = true;
3614 mRelaunchingActivities.add(target);
3615 queueOrSendMessage(H.RELAUNCH_ACTIVITY, target);
3619 target.startsNotResumed = notResumed;
3620 target.onlyLocalRequest = false;
3622 if (config != null) {
3623 target.createdConfig = config;
3625 target.pendingConfigChanges |= configChanges;
3629 private void handleRelaunchActivity(ActivityClientRecord tmp) {
3630 // If we are getting ready to gc after going to the background, well
3631 // we are back active so skip it.
3632 unscheduleGcIdler();
3634 Configuration changedConfig = null;
3635 int configChanges = 0;
3637 // First: make sure we have the most recent configuration and most
3638 // recent version of the activity, or skip it if some previous call
3639 // had taken a more recent version.
3640 synchronized (mPackages) {
3641 int N = mRelaunchingActivities.size();
3642 IBinder token = tmp.token;
3644 for (int i=0; i<N; i++) {
3645 ActivityClientRecord r = mRelaunchingActivities.get(i);
3646 if (r.token == token) {
3648 configChanges |= tmp.pendingConfigChanges;
3649 mRelaunchingActivities.remove(i);
3656 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Abort, activity not relaunching!");
3660 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Relaunching activity "
3661 + tmp.token + " with configChanges=0x"
3662 + Integer.toHexString(configChanges));
3664 if (mPendingConfiguration != null) {
3665 changedConfig = mPendingConfiguration;
3666 mPendingConfiguration = null;
3670 if (tmp.createdConfig != null) {
3671 // If the activity manager is passing us its current config,
3672 // assume that is really what we want regardless of what we
3673 // may have pending.
3674 if (mConfiguration == null
3675 || (tmp.createdConfig.isOtherSeqNewer(mConfiguration)
3676 && mConfiguration.diff(tmp.createdConfig) != 0)) {
3677 if (changedConfig == null
3678 || tmp.createdConfig.isOtherSeqNewer(changedConfig)) {
3679 changedConfig = tmp.createdConfig;
3684 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Relaunching activity "
3685 + tmp.token + ": changedConfig=" + changedConfig);
3687 // If there was a pending configuration change, execute it first.
3688 if (changedConfig != null) {
3689 mCurDefaultDisplayDpi = changedConfig.densityDpi;
3690 updateDefaultDensity();
3691 handleConfigurationChanged(changedConfig, null);
3694 ActivityClientRecord r = mActivities.get(tmp.token);
3695 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handling relaunch of " + r);
3700 r.activity.mConfigChangeFlags |= configChanges;
3701 r.onlyLocalRequest = tmp.onlyLocalRequest;
3702 Intent currentIntent = r.activity.mIntent;
3704 r.activity.mChangingConfigurations = true;
3706 // Need to ensure state is saved.
3708 performPauseActivity(r.token, false, r.isPreHoneycomb());
3710 if (r.state == null && !r.stopped && !r.isPreHoneycomb()) {
3711 r.state = new Bundle();
3712 r.state.setAllowFds(false);
3713 mInstrumentation.callActivityOnSaveInstanceState(r.activity, r.state);
3716 handleDestroyActivity(r.token, false, configChanges, true);
3720 r.hideForNow = false;
3722 // Merge any pending results and pending intents; don't just replace them
3723 if (tmp.pendingResults != null) {
3724 if (r.pendingResults == null) {
3725 r.pendingResults = tmp.pendingResults;
3727 r.pendingResults.addAll(tmp.pendingResults);
3730 if (tmp.pendingIntents != null) {
3731 if (r.pendingIntents == null) {
3732 r.pendingIntents = tmp.pendingIntents;
3734 r.pendingIntents.addAll(tmp.pendingIntents);
3737 r.startsNotResumed = tmp.startsNotResumed;
3739 handleLaunchActivity(r, currentIntent);
3742 private void handleRequestThumbnail(IBinder token) {
3743 ActivityClientRecord r = mActivities.get(token);
3744 Bitmap thumbnail = createThumbnailBitmap(r);
3745 CharSequence description = null;
3747 description = r.activity.onCreateDescription();
3748 } catch (Exception e) {
3749 if (!mInstrumentation.onException(r.activity, e)) {
3750 throw new RuntimeException(
3751 "Unable to create description of activity "
3752 + r.intent.getComponent().toShortString()
3753 + ": " + e.toString(), e);
3756 //System.out.println("Reporting top thumbnail " + thumbnail);
3758 ActivityManagerNative.getDefault().reportThumbnail(
3759 token, thumbnail, description);
3760 } catch (RemoteException ex) {
3764 ArrayList<ComponentCallbacks2> collectComponentCallbacks(
3765 boolean allActivities, Configuration newConfig) {
3766 ArrayList<ComponentCallbacks2> callbacks
3767 = new ArrayList<ComponentCallbacks2>();
3769 synchronized (mPackages) {
3770 final int N = mAllApplications.size();
3771 for (int i=0; i<N; i++) {
3772 callbacks.add(mAllApplications.get(i));
3774 if (mActivities.size() > 0) {
3775 for (ActivityClientRecord ar : mActivities.values()) {
3776 Activity a = ar.activity;
3778 Configuration thisConfig = applyConfigCompatMainThread(mCurDefaultDisplayDpi,
3779 newConfig, ar.packageInfo.mCompatibilityInfo.getIfNeeded());
3780 if (!ar.activity.mFinished && (allActivities || !ar.paused)) {
3781 // If the activity is currently resumed, its configuration
3782 // needs to change right now.
3784 } else if (thisConfig != null) {
3785 // Otherwise, we will tell it about the change
3786 // the next time it is resumed or shown. Note that
3787 // the activity manager may, before then, decide the
3788 // activity needs to be destroyed to handle its new
3790 if (DEBUG_CONFIGURATION) {
3791 Slog.v(TAG, "Setting activity "
3792 + ar.activityInfo.name + " newConfig=" + thisConfig);
3794 ar.newConfig = thisConfig;
3799 if (mServices.size() > 0) {
3800 for (Service service : mServices.values()) {
3801 callbacks.add(service);
3805 synchronized (mProviderMap) {
3806 if (mLocalProviders.size() > 0) {
3807 for (ProviderClientRecord providerClientRecord : mLocalProviders.values()) {
3808 callbacks.add(providerClientRecord.mLocalProvider);
3816 private static void performConfigurationChanged(ComponentCallbacks2 cb, Configuration config) {
3817 // Only for Activity objects, check that they actually call up to their
3818 // superclass implementation. ComponentCallbacks2 is an interface, so
3819 // we check the runtime type and act accordingly.
3820 Activity activity = (cb instanceof Activity) ? (Activity) cb : null;
3821 if (activity != null) {
3822 activity.mCalled = false;
3825 boolean shouldChangeConfig = false;
3826 if ((activity == null) || (activity.mCurrentConfig == null)) {
3827 shouldChangeConfig = true;
3830 // If the new config is the same as the config this Activity
3831 // is already running with then don't bother calling
3832 // onConfigurationChanged
3833 int diff = activity.mCurrentConfig.diff(config);
3835 // If this activity doesn't handle any of the config changes
3836 // then don't bother calling onConfigurationChanged as we're
3837 // going to destroy it.
3838 if ((~activity.mActivityInfo.getRealConfigChanged() & diff) == 0) {
3839 shouldChangeConfig = true;
3844 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Config callback " + cb
3845 + ": shouldChangeConfig=" + shouldChangeConfig);
3846 if (shouldChangeConfig) {
3847 cb.onConfigurationChanged(config);
3849 if (activity != null) {
3850 if (!activity.mCalled) {
3851 throw new SuperNotCalledException(
3852 "Activity " + activity.getLocalClassName() +
3853 " did not call through to super.onConfigurationChanged()");
3855 activity.mConfigChangeFlags = 0;
3856 activity.mCurrentConfig = new Configuration(config);
3861 public final void applyConfigurationToResources(Configuration config) {
3862 synchronized (mPackages) {
3863 applyConfigurationToResourcesLocked(config, null);
3867 final boolean applyConfigurationToResourcesLocked(Configuration config,
3868 CompatibilityInfo compat) {
3869 if (mResConfiguration == null) {
3870 mResConfiguration = new Configuration();
3872 if (!mResConfiguration.isOtherSeqNewer(config) && compat == null) {
3873 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Skipping new config: curSeq="
3874 + mResConfiguration.seq + ", newSeq=" + config.seq);
3877 int changes = mResConfiguration.updateFrom(config);
3878 flushDisplayMetricsLocked();
3879 DisplayMetrics defaultDisplayMetrics = getDisplayMetricsLocked(
3880 Display.DEFAULT_DISPLAY, null);
3882 if (compat != null && (mResCompatibilityInfo == null ||
3883 !mResCompatibilityInfo.equals(compat))) {
3884 mResCompatibilityInfo = compat;
3885 changes |= ActivityInfo.CONFIG_SCREEN_LAYOUT
3886 | ActivityInfo.CONFIG_SCREEN_SIZE
3887 | ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE;
3890 // set it for java, this also affects newly created Resources
3891 if (config.locale != null) {
3892 Locale.setDefault(config.locale);
3895 Resources.updateSystemConfiguration(config, defaultDisplayMetrics, compat);
3897 ApplicationPackageManager.configurationChanged();
3898 //Slog.i(TAG, "Configuration changed in " + currentPackageName());
3900 Configuration tmpConfig = null;
3902 Iterator<Map.Entry<ResourcesKey, WeakReference<Resources>>> it =
3903 mActiveResources.entrySet().iterator();
3904 while (it.hasNext()) {
3905 Map.Entry<ResourcesKey, WeakReference<Resources>> entry = it.next();
3906 Resources r = entry.getValue().get();
3908 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Changing resources "
3909 + r + " config to: " + config);
3910 int displayId = entry.getKey().mDisplayId;
3911 boolean isDefaultDisplay = (displayId == Display.DEFAULT_DISPLAY);
3912 DisplayMetrics dm = defaultDisplayMetrics;
3913 Configuration overrideConfig = entry.getKey().mOverrideConfiguration;
3914 if (!isDefaultDisplay || overrideConfig != null) {
3915 if (tmpConfig == null) {
3916 tmpConfig = new Configuration();
3918 tmpConfig.setTo(config);
3919 if (!isDefaultDisplay) {
3920 dm = getDisplayMetricsLocked(displayId, null);
3921 applyNonDefaultDisplayMetricsToConfigurationLocked(dm, tmpConfig);
3923 if (overrideConfig != null) {
3924 tmpConfig.updateFrom(overrideConfig);
3926 r.updateConfiguration(tmpConfig, dm, compat);
3928 r.updateConfiguration(config, dm, compat);
3930 //Slog.i(TAG, "Updated app resources " + v.getKey()
3931 // + " " + r + ": " + r.getConfiguration());
3933 //Slog.i(TAG, "Removing old resources " + v.getKey());
3938 return changes != 0;
3941 final void applyNonDefaultDisplayMetricsToConfigurationLocked(
3942 DisplayMetrics dm, Configuration config) {
3943 config.touchscreen = Configuration.TOUCHSCREEN_NOTOUCH;
3944 config.densityDpi = dm.densityDpi;
3945 config.screenWidthDp = (int)(dm.widthPixels / dm.density);
3946 config.screenHeightDp = (int)(dm.heightPixels / dm.density);
3947 int sl = Configuration.resetScreenLayout(config.screenLayout);
3948 if (dm.widthPixels > dm.heightPixels) {
3949 config.orientation = Configuration.ORIENTATION_LANDSCAPE;
3950 config.screenLayout = Configuration.reduceScreenLayout(sl,
3951 config.screenWidthDp, config.screenHeightDp);
3953 config.orientation = Configuration.ORIENTATION_PORTRAIT;
3954 config.screenLayout = Configuration.reduceScreenLayout(sl,
3955 config.screenHeightDp, config.screenWidthDp);
3957 config.smallestScreenWidthDp = config.screenWidthDp; // assume screen does not rotate
3958 config.compatScreenWidthDp = config.screenWidthDp;
3959 config.compatScreenHeightDp = config.screenHeightDp;
3960 config.compatSmallestScreenWidthDp = config.smallestScreenWidthDp;
3963 final Configuration applyCompatConfiguration(int displayDensity) {
3964 Configuration config = mConfiguration;
3965 if (mCompatConfiguration == null) {
3966 mCompatConfiguration = new Configuration();
3968 mCompatConfiguration.setTo(mConfiguration);
3969 if (mResCompatibilityInfo != null && !mResCompatibilityInfo.supportsScreen()) {
3970 mResCompatibilityInfo.applyToConfiguration(displayDensity, mCompatConfiguration);
3971 config = mCompatConfiguration;
3976 final void handleConfigurationChanged(Configuration config, CompatibilityInfo compat) {
3980 synchronized (mPackages) {
3981 if (mPendingConfiguration != null) {
3982 if (!mPendingConfiguration.isOtherSeqNewer(config)) {
3983 config = mPendingConfiguration;
3984 mCurDefaultDisplayDpi = config.densityDpi;
3985 updateDefaultDensity();
3987 mPendingConfiguration = null;
3990 if (config == null) {
3994 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handle configuration changed: "
3997 applyConfigurationToResourcesLocked(config, compat);
3999 if (mConfiguration == null) {
4000 mConfiguration = new Configuration();
4002 if (!mConfiguration.isOtherSeqNewer(config) && compat == null) {
4005 configDiff = mConfiguration.diff(config);
4006 mConfiguration.updateFrom(config);
4007 config = applyCompatConfiguration(mCurDefaultDisplayDpi);
4010 ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(false, config);
4012 // Cleanup hardware accelerated stuff
4013 WindowManagerGlobal.getInstance().trimLocalMemory();
4015 freeTextLayoutCachesIfNeeded(configDiff);
4017 if (callbacks != null) {
4018 final int N = callbacks.size();
4019 for (int i=0; i<N; i++) {
4020 performConfigurationChanged(callbacks.get(i), config);
4025 final void freeTextLayoutCachesIfNeeded(int configDiff) {
4026 if (configDiff != 0) {
4027 // Ask text layout engine to free its caches if there is a locale change
4028 boolean hasLocaleConfigChange = ((configDiff & ActivityInfo.CONFIG_LOCALE) != 0);
4029 if (hasLocaleConfigChange) {
4030 Canvas.freeTextLayoutCaches();
4031 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Cleared TextLayout Caches");
4036 final void handleActivityConfigurationChanged(IBinder token) {
4037 ActivityClientRecord r = mActivities.get(token);
4038 if (r == null || r.activity == null) {
4042 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handle activity config changed: "
4043 + r.activityInfo.name);
4045 performConfigurationChanged(r.activity, mCompatConfiguration);
4047 freeTextLayoutCachesIfNeeded(r.activity.mCurrentConfig.diff(mCompatConfiguration));
4050 final void handleProfilerControl(boolean start, ProfilerControlData pcd, int profileType) {
4053 switch (profileType) {
4055 mProfiler.setProfiler(pcd.path, pcd.fd);
4056 mProfiler.autoStopProfiler = false;
4057 mProfiler.startProfiling();
4060 } catch (RuntimeException e) {
4061 Slog.w(TAG, "Profiling failed on path " + pcd.path
4062 + " -- can the process access this path?");
4066 } catch (IOException e) {
4067 Slog.w(TAG, "Failure closing profile fd", e);
4071 switch (profileType) {
4073 mProfiler.stopProfiling();
4079 static final void handleDumpHeap(boolean managed, DumpHeapData dhd) {
4082 Debug.dumpHprofData(dhd.path, dhd.fd.getFileDescriptor());
4083 } catch (IOException e) {
4084 Slog.w(TAG, "Managed heap dump failed on path " + dhd.path
4085 + " -- can the process access this path?");
4089 } catch (IOException e) {
4090 Slog.w(TAG, "Failure closing profile fd", e);
4094 Debug.dumpNativeHeap(dhd.fd.getFileDescriptor());
4098 final void handleDispatchPackageBroadcast(int cmd, String[] packages) {
4099 boolean hasPkgInfo = false;
4100 if (packages != null) {
4101 for (int i=packages.length-1; i>=0; i--) {
4102 //Slog.i(TAG, "Cleaning old package: " + packages[i]);
4104 WeakReference<LoadedApk> ref;
4105 ref = mPackages.get(packages[i]);
4106 if (ref != null && ref.get() != null) {
4109 ref = mResourcePackages.get(packages[i]);
4110 if (ref != null && ref.get() != null) {
4115 mPackages.remove(packages[i]);
4116 mResourcePackages.remove(packages[i]);
4119 ApplicationPackageManager.handlePackageBroadcast(cmd, packages,
4123 final void handleLowMemory() {
4124 ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(true, null);
4126 final int N = callbacks.size();
4127 for (int i=0; i<N; i++) {
4128 callbacks.get(i).onLowMemory();
4131 // Ask SQLite to free up as much memory as it can, mostly from its page caches.
4132 if (Process.myUid() != Process.SYSTEM_UID) {
4133 int sqliteReleased = SQLiteDatabase.releaseMemory();
4134 EventLog.writeEvent(SQLITE_MEM_RELEASED_EVENT_LOG_TAG, sqliteReleased);
4137 // Ask graphics to free up as much as possible (font/image caches)
4138 Canvas.freeCaches();
4140 // Ask text layout engine to free also as much as possible
4141 Canvas.freeTextLayoutCaches();
4143 BinderInternal.forceGc("mem");
4146 final void handleTrimMemory(int level) {
4147 if (DEBUG_MEMORY_TRIM) Slog.v(TAG, "Trimming memory to level: " + level);
4149 final WindowManagerGlobal windowManager = WindowManagerGlobal.getInstance();
4150 windowManager.startTrimMemory(level);
4152 ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(true, null);
4154 final int N = callbacks.size();
4155 for (int i = 0; i < N; i++) {
4156 callbacks.get(i).onTrimMemory(level);
4159 windowManager.endTrimMemory();
4162 private void setupGraphicsSupport(LoadedApk info, File cacheDir) {
4163 if (Process.isIsolated()) {
4164 // Isolated processes aren't going to do UI.
4168 int uid = Process.myUid();
4169 String[] packages = getPackageManager().getPackagesForUid(uid);
4171 // If there are several packages in this application we won't
4172 // initialize the graphics disk caches
4173 if (packages != null && packages.length == 1) {
4174 HardwareRenderer.setupDiskCache(cacheDir);
4175 RenderScript.setupDiskCache(cacheDir);
4177 } catch (RemoteException e) {
4182 private void updateDefaultDensity() {
4183 if (mCurDefaultDisplayDpi != Configuration.DENSITY_DPI_UNDEFINED
4184 && mCurDefaultDisplayDpi != DisplayMetrics.DENSITY_DEVICE
4185 && !mDensityCompatMode) {
4186 Slog.i(TAG, "Switching default density from "
4187 + DisplayMetrics.DENSITY_DEVICE + " to "
4188 + mCurDefaultDisplayDpi);
4189 DisplayMetrics.DENSITY_DEVICE = mCurDefaultDisplayDpi;
4190 Bitmap.setDefaultDensity(DisplayMetrics.DENSITY_DEFAULT);
4194 private void handleBindApplication(AppBindData data) {
4195 mBoundApplication = data;
4196 mConfiguration = new Configuration(data.config);
4197 mCompatConfiguration = new Configuration(data.config);
4199 mProfiler = new Profiler();
4200 mProfiler.profileFile = data.initProfileFile;
4201 mProfiler.profileFd = data.initProfileFd;
4202 mProfiler.autoStopProfiler = data.initAutoStopProfiler;
4204 // send up app name; do this *before* waiting for debugger
4205 Process.setArgV0(data.processName);
4206 android.ddm.DdmHandleAppName.setAppName(data.processName,
4207 UserHandle.myUserId());
4209 if (data.persistent) {
4210 // Persistent processes on low-memory devices do not get to
4211 // use hardware accelerated drawing, since this can add too much
4212 // overhead to the process.
4213 if (!ActivityManager.isHighEndGfx()) {
4214 HardwareRenderer.disable(false);
4218 if (mProfiler.profileFd != null) {
4219 mProfiler.startProfiling();
4222 // If the app is Honeycomb MR1 or earlier, switch its AsyncTask
4223 // implementation to use the pool executor. Normally, we use the
4224 // serialized executor as the default. This has to happen in the
4225 // main thread so the main looper is set right.
4226 if (data.appInfo.targetSdkVersion <= android.os.Build.VERSION_CODES.HONEYCOMB_MR1) {
4227 AsyncTask.setDefaultExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
4231 * Before spawning a new process, reset the time zone to be the system time zone.
4232 * This needs to be done because the system time zone could have changed after the
4233 * the spawning of this process. Without doing this this process would have the incorrect
4236 TimeZone.setDefault(null);
4239 * Initialize the default locale in this process for the reasons we set the time zone.
4241 Locale.setDefault(data.config.locale);
4244 * Update the system configuration since its preloaded and might not
4245 * reflect configuration changes. The configuration object passed
4246 * in AppBindData can be safely assumed to be up to date
4248 applyConfigurationToResourcesLocked(data.config, data.compatInfo);
4249 mCurDefaultDisplayDpi = data.config.densityDpi;
4250 applyCompatConfiguration(mCurDefaultDisplayDpi);
4252 data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
4255 * Switch this process to density compatibility mode if needed.
4257 if ((data.appInfo.flags&ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES)
4259 mDensityCompatMode = true;
4260 Bitmap.setDefaultDensity(DisplayMetrics.DENSITY_DEFAULT);
4262 updateDefaultDensity();
4264 final ContextImpl appContext = new ContextImpl();
4265 appContext.init(data.info, null, this);
4266 if (!Process.isIsolated()) {
4267 final File cacheDir = appContext.getCacheDir();
4269 if (cacheDir != null) {
4270 // Provide a usable directory for temporary files
4271 System.setProperty("java.io.tmpdir", cacheDir.getAbsolutePath());
4273 setupGraphicsSupport(data.info, cacheDir);
4275 Log.e(TAG, "Unable to setupGraphicsSupport due to missing cache directory");
4279 * For system applications on userdebug/eng builds, log stack
4280 * traces of disk and network access to dropbox for analysis.
4282 if ((data.appInfo.flags &
4283 (ApplicationInfo.FLAG_SYSTEM |
4284 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0) {
4285 StrictMode.conditionallyEnableDebugLogging();
4289 * For apps targetting SDK Honeycomb or later, we don't allow
4290 * network usage on the main event loop / UI thread.
4292 * Note to those grepping: this is what ultimately throws
4293 * NetworkOnMainThreadException ...
4295 if (data.appInfo.targetSdkVersion > 9) {
4296 StrictMode.enableDeathOnNetwork();
4299 if (data.debugMode != IApplicationThread.DEBUG_OFF) {
4300 // XXX should have option to change the port.
4301 Debug.changeDebugPort(8100);
4302 if (data.debugMode == IApplicationThread.DEBUG_WAIT) {
4303 Slog.w(TAG, "Application " + data.info.getPackageName()
4304 + " is waiting for the debugger on port 8100...");
4306 IActivityManager mgr = ActivityManagerNative.getDefault();
4308 mgr.showWaitingForDebugger(mAppThread, true);
4309 } catch (RemoteException ex) {
4312 Debug.waitForDebugger();
4315 mgr.showWaitingForDebugger(mAppThread, false);
4316 } catch (RemoteException ex) {
4320 Slog.w(TAG, "Application " + data.info.getPackageName()
4321 + " can be debugged on port 8100...");
4325 // Enable OpenGL tracing if required
4326 if (data.enableOpenGlTrace) {
4327 GLUtils.setTracingLevel(1);
4330 // Allow application-generated systrace messages if we're debuggable.
4331 boolean appTracingAllowed = (data.appInfo.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0;
4332 Trace.setAppTracingAllowed(appTracingAllowed);
4335 * Initialize the default http proxy in this process for the reasons we set the time zone.
4337 IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE);
4339 // In pre-boot mode (doing initial launch to collect password), not
4340 // all system is up. This includes the connectivity service, so don't
4341 // crash if we can't get it.
4342 IConnectivityManager service = IConnectivityManager.Stub.asInterface(b);
4344 ProxyProperties proxyProperties = service.getProxy();
4345 Proxy.setHttpProxySystemProperty(proxyProperties);
4346 } catch (RemoteException e) {}
4349 if (data.instrumentationName != null) {
4350 InstrumentationInfo ii = null;
4352 ii = appContext.getPackageManager().
4353 getInstrumentationInfo(data.instrumentationName, 0);
4354 } catch (PackageManager.NameNotFoundException e) {
4357 throw new RuntimeException(
4358 "Unable to find instrumentation info for: "
4359 + data.instrumentationName);
4362 mInstrumentationAppDir = ii.sourceDir;
4363 mInstrumentationAppLibraryDir = ii.nativeLibraryDir;
4364 mInstrumentationAppPackage = ii.packageName;
4365 mInstrumentedAppDir = data.info.getAppDir();
4366 mInstrumentedAppLibraryDir = data.info.getLibDir();
4368 ApplicationInfo instrApp = new ApplicationInfo();
4369 instrApp.packageName = ii.packageName;
4370 instrApp.sourceDir = ii.sourceDir;
4371 instrApp.publicSourceDir = ii.publicSourceDir;
4372 instrApp.dataDir = ii.dataDir;
4373 instrApp.nativeLibraryDir = ii.nativeLibraryDir;
4374 LoadedApk pi = getPackageInfo(instrApp, data.compatInfo,
4375 appContext.getClassLoader(), false, true);
4376 ContextImpl instrContext = new ContextImpl();
4377 instrContext.init(pi, null, this);
4380 java.lang.ClassLoader cl = instrContext.getClassLoader();
4381 mInstrumentation = (Instrumentation)
4382 cl.loadClass(data.instrumentationName.getClassName()).newInstance();
4383 } catch (Exception e) {
4384 throw new RuntimeException(
4385 "Unable to instantiate instrumentation "
4386 + data.instrumentationName + ": " + e.toString(), e);
4389 mInstrumentation.init(this, instrContext, appContext,
4390 new ComponentName(ii.packageName, ii.name), data.instrumentationWatcher,
4391 data.instrumentationUiAutomationConnection);
4393 if (mProfiler.profileFile != null && !ii.handleProfiling
4394 && mProfiler.profileFd == null) {
4395 mProfiler.handlingProfiling = true;
4396 File file = new File(mProfiler.profileFile);
4397 file.getParentFile().mkdirs();
4398 Debug.startMethodTracing(file.toString(), 8 * 1024 * 1024);
4402 mInstrumentation = new Instrumentation();
4405 if ((data.appInfo.flags&ApplicationInfo.FLAG_LARGE_HEAP) != 0) {
4406 dalvik.system.VMRuntime.getRuntime().clearGrowthLimit();
4409 // Allow disk access during application and provider setup. This could
4410 // block processing ordered broadcasts, but later processing would
4411 // probably end up doing the same disk access.
4412 final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskWrites();
4414 // If the app is being launched for full backup or restore, bring it up in
4415 // a restricted environment with the base application class.
4416 Application app = data.info.makeApplication(data.restrictedBackupMode, null);
4417 mInitialApplication = app;
4419 // don't bring up providers in restricted mode; they may depend on the
4420 // app's custom Application class
4421 if (!data.restrictedBackupMode) {
4422 List<ProviderInfo> providers = data.providers;
4423 if (providers != null) {
4424 installContentProviders(app, providers);
4425 // For process that contains content providers, we want to
4426 // ensure that the JIT is enabled "at some point".
4427 mH.sendEmptyMessageDelayed(H.ENABLE_JIT, 10*1000);
4431 // Do this after providers, since instrumentation tests generally start their
4432 // test thread at this point, and we don't want that racing.
4434 mInstrumentation.onCreate(data.instrumentationArgs);
4436 catch (Exception e) {
4437 throw new RuntimeException(
4438 "Exception thrown in onCreate() of "
4439 + data.instrumentationName + ": " + e.toString(), e);
4443 mInstrumentation.callApplicationOnCreate(app);
4444 } catch (Exception e) {
4445 if (!mInstrumentation.onException(app, e)) {
4446 throw new RuntimeException(
4447 "Unable to create application " + app.getClass().getName()
4448 + ": " + e.toString(), e);
4452 StrictMode.setThreadPolicy(savedPolicy);
4456 /*package*/ final void finishInstrumentation(int resultCode, Bundle results) {
4457 IActivityManager am = ActivityManagerNative.getDefault();
4458 if (mProfiler.profileFile != null && mProfiler.handlingProfiling
4459 && mProfiler.profileFd == null) {
4460 Debug.stopMethodTracing();
4462 //Slog.i(TAG, "am: " + ActivityManagerNative.getDefault()
4463 // + ", app thr: " + mAppThread);
4465 am.finishInstrumentation(mAppThread, resultCode, results);
4466 } catch (RemoteException ex) {
4470 private void installContentProviders(
4471 Context context, List<ProviderInfo> providers) {
4472 final ArrayList<IActivityManager.ContentProviderHolder> results =
4473 new ArrayList<IActivityManager.ContentProviderHolder>();
4475 for (ProviderInfo cpi : providers) {
4476 if (DEBUG_PROVIDER) {
4477 StringBuilder buf = new StringBuilder(128);
4479 buf.append(cpi.authority);
4481 buf.append(cpi.name);
4482 Log.i(TAG, buf.toString());
4484 IActivityManager.ContentProviderHolder cph = installProvider(context, null, cpi,
4485 false /*noisy*/, true /*noReleaseNeeded*/, true /*stable*/);
4487 cph.noReleaseNeeded = true;
4493 ActivityManagerNative.getDefault().publishContentProviders(
4494 getApplicationThread(), results);
4495 } catch (RemoteException ex) {
4499 public final IContentProvider acquireProvider(
4500 Context c, String auth, int userId, boolean stable) {
4501 final IContentProvider provider = acquireExistingProvider(c, auth, userId, stable);
4502 if (provider != null) {
4506 // There is a possible race here. Another thread may try to acquire
4507 // the same provider at the same time. When this happens, we want to ensure
4508 // that the first one wins.
4509 // Note that we cannot hold the lock while acquiring and installing the
4510 // provider since it might take a long time to run and it could also potentially
4511 // be re-entrant in the case where the provider is in the same process.
4512 IActivityManager.ContentProviderHolder holder = null;
4514 holder = ActivityManagerNative.getDefault().getContentProvider(
4515 getApplicationThread(), auth, userId, stable);
4516 } catch (RemoteException ex) {
4518 if (holder == null) {
4519 Slog.e(TAG, "Failed to find provider info for " + auth);
4523 // Install provider will increment the reference count for us, and break
4524 // any ties in the race.
4525 holder = installProvider(c, holder, holder.info,
4526 true /*noisy*/, holder.noReleaseNeeded, stable);
4527 return holder.provider;
4530 private final void incProviderRefLocked(ProviderRefCount prc, boolean stable) {
4532 prc.stableCount += 1;
4533 if (prc.stableCount == 1) {
4534 // We are acquiring a new stable reference on the provider.
4536 if (prc.removePending) {
4537 // We have a pending remove operation, which is holding the
4538 // last unstable reference. At this point we are converting
4539 // that unstable reference to our new stable reference.
4541 // Cancel the removal of the provider.
4542 if (DEBUG_PROVIDER) {
4543 Slog.v(TAG, "incProviderRef: stable "
4544 + "snatched provider from the jaws of death");
4546 prc.removePending = false;
4547 // There is a race! It fails to remove the message, which
4548 // will be handled in completeRemoveProvider().
4549 mH.removeMessages(H.REMOVE_PROVIDER, prc);
4554 if (DEBUG_PROVIDER) {
4555 Slog.v(TAG, "incProviderRef Now stable - "
4556 + prc.holder.info.name + ": unstableDelta="
4559 ActivityManagerNative.getDefault().refContentProvider(
4560 prc.holder.connection, 1, unstableDelta);
4561 } catch (RemoteException e) {
4562 //do nothing content provider object is dead any way
4566 prc.unstableCount += 1;
4567 if (prc.unstableCount == 1) {
4568 // We are acquiring a new unstable reference on the provider.
4569 if (prc.removePending) {
4570 // Oh look, we actually have a remove pending for the
4571 // provider, which is still holding the last unstable
4572 // reference. We just need to cancel that to take new
4573 // ownership of the reference.
4574 if (DEBUG_PROVIDER) {
4575 Slog.v(TAG, "incProviderRef: unstable "
4576 + "snatched provider from the jaws of death");
4578 prc.removePending = false;
4579 mH.removeMessages(H.REMOVE_PROVIDER, prc);
4581 // First unstable ref, increment our count in the
4582 // activity manager.
4584 if (DEBUG_PROVIDER) {
4585 Slog.v(TAG, "incProviderRef: Now unstable - "
4586 + prc.holder.info.name);
4588 ActivityManagerNative.getDefault().refContentProvider(
4589 prc.holder.connection, 0, 1);
4590 } catch (RemoteException e) {
4591 //do nothing content provider object is dead any way
4598 public final IContentProvider acquireExistingProvider(
4599 Context c, String auth, int userId, boolean stable) {
4600 synchronized (mProviderMap) {
4601 final ProviderKey key = new ProviderKey(auth, userId);
4602 final ProviderClientRecord pr = mProviderMap.get(key);
4607 IContentProvider provider = pr.mProvider;
4608 IBinder jBinder = provider.asBinder();
4609 if (!jBinder.isBinderAlive()) {
4610 // The hosting process of the provider has died; we can't
4612 Log.i(TAG, "Acquiring provider " + auth + " for user " + userId
4613 + ": existing object's process dead");
4614 handleUnstableProviderDiedLocked(jBinder, true);
4618 // Only increment the ref count if we have one. If we don't then the
4619 // provider is not reference counted and never needs to be released.
4620 ProviderRefCount prc = mProviderRefCountMap.get(jBinder);
4622 incProviderRefLocked(prc, stable);
4628 public final boolean releaseProvider(IContentProvider provider, boolean stable) {
4629 if (provider == null) {
4633 IBinder jBinder = provider.asBinder();
4634 synchronized (mProviderMap) {
4635 ProviderRefCount prc = mProviderRefCountMap.get(jBinder);
4637 // The provider has no ref count, no release is needed.
4641 boolean lastRef = false;
4643 if (prc.stableCount == 0) {
4644 if (DEBUG_PROVIDER) Slog.v(TAG,
4645 "releaseProvider: stable ref count already 0, how?");
4648 prc.stableCount -= 1;
4649 if (prc.stableCount == 0) {
4650 // What we do at this point depends on whether there are
4651 // any unstable refs left: if there are, we just tell the
4652 // activity manager to decrement its stable count; if there
4653 // aren't, we need to enqueue this provider to be removed,
4654 // and convert to holding a single unstable ref while
4656 lastRef = prc.unstableCount == 0;
4658 if (DEBUG_PROVIDER) {
4659 Slog.v(TAG, "releaseProvider: No longer stable w/lastRef="
4660 + lastRef + " - " + prc.holder.info.name);
4662 ActivityManagerNative.getDefault().refContentProvider(
4663 prc.holder.connection, -1, lastRef ? 1 : 0);
4664 } catch (RemoteException e) {
4665 //do nothing content provider object is dead any way
4669 if (prc.unstableCount == 0) {
4670 if (DEBUG_PROVIDER) Slog.v(TAG,
4671 "releaseProvider: unstable ref count already 0, how?");
4674 prc.unstableCount -= 1;
4675 if (prc.unstableCount == 0) {
4676 // If this is the last reference, we need to enqueue
4677 // this provider to be removed instead of telling the
4678 // activity manager to remove it at this point.
4679 lastRef = prc.stableCount == 0;
4682 if (DEBUG_PROVIDER) {
4683 Slog.v(TAG, "releaseProvider: No longer unstable - "
4684 + prc.holder.info.name);
4686 ActivityManagerNative.getDefault().refContentProvider(
4687 prc.holder.connection, 0, -1);
4688 } catch (RemoteException e) {
4689 //do nothing content provider object is dead any way
4696 if (!prc.removePending) {
4697 // Schedule the actual remove asynchronously, since we don't know the context
4698 // this will be called in.
4699 // TODO: it would be nice to post a delayed message, so
4700 // if we come back and need the same provider quickly
4701 // we will still have it available.
4702 if (DEBUG_PROVIDER) {
4703 Slog.v(TAG, "releaseProvider: Enqueueing pending removal - "
4704 + prc.holder.info.name);
4706 prc.removePending = true;
4707 Message msg = mH.obtainMessage(H.REMOVE_PROVIDER, prc);
4708 mH.sendMessage(msg);
4710 Slog.w(TAG, "Duplicate remove pending of provider " + prc.holder.info.name);
4717 final void completeRemoveProvider(ProviderRefCount prc) {
4718 synchronized (mProviderMap) {
4719 if (!prc.removePending) {
4720 // There was a race! Some other client managed to acquire
4721 // the provider before the removal was completed.
4722 // Abort the removal. We will do it later.
4723 if (DEBUG_PROVIDER) Slog.v(TAG, "completeRemoveProvider: lost the race, "
4724 + "provider still in use");
4728 // More complicated race!! Some client managed to acquire the
4729 // provider and release it before the removal was completed.
4730 // Continue the removal, and abort the next remove message.
4731 prc.removePending = false;
4733 final IBinder jBinder = prc.holder.provider.asBinder();
4734 ProviderRefCount existingPrc = mProviderRefCountMap.get(jBinder);
4735 if (existingPrc == prc) {
4736 mProviderRefCountMap.remove(jBinder);
4739 Iterator<ProviderClientRecord> iter = mProviderMap.values().iterator();
4740 while (iter.hasNext()) {
4741 ProviderClientRecord pr = iter.next();
4742 IBinder myBinder = pr.mProvider.asBinder();
4743 if (myBinder == jBinder) {
4750 if (DEBUG_PROVIDER) {
4751 Slog.v(TAG, "removeProvider: Invoking ActivityManagerNative."
4752 + "removeContentProvider(" + prc.holder.info.name + ")");
4754 ActivityManagerNative.getDefault().removeContentProvider(
4755 prc.holder.connection, false);
4756 } catch (RemoteException e) {
4757 //do nothing content provider object is dead any way
4761 final void handleUnstableProviderDied(IBinder provider, boolean fromClient) {
4762 synchronized (mProviderMap) {
4763 handleUnstableProviderDiedLocked(provider, fromClient);
4767 final void handleUnstableProviderDiedLocked(IBinder provider, boolean fromClient) {
4768 ProviderRefCount prc = mProviderRefCountMap.get(provider);
4770 if (DEBUG_PROVIDER) Slog.v(TAG, "Cleaning up dead provider "
4771 + provider + " " + prc.holder.info.name);
4772 mProviderRefCountMap.remove(provider);
4773 if (prc.client != null && prc.client.mNames != null) {
4774 for (String name : prc.client.mNames) {
4775 ProviderClientRecord pr = mProviderMap.get(name);
4776 if (pr != null && pr.mProvider.asBinder() == provider) {
4777 Slog.i(TAG, "Removing dead content provider: " + name);
4778 mProviderMap.remove(name);
4783 // We found out about this due to execution in our client
4784 // code. Tell the activity manager about it now, to ensure
4785 // that the next time we go to do anything with the provider
4786 // it knows it is dead (so we don't race with its death
4789 ActivityManagerNative.getDefault().unstableProviderDied(
4790 prc.holder.connection);
4791 } catch (RemoteException e) {
4792 //do nothing content provider object is dead any way
4798 private ProviderClientRecord installProviderAuthoritiesLocked(IContentProvider provider,
4799 ContentProvider localProvider, IActivityManager.ContentProviderHolder holder) {
4800 final String auths[] = PATTERN_SEMICOLON.split(holder.info.authority);
4801 final int userId = UserHandle.getUserId(holder.info.applicationInfo.uid);
4803 final ProviderClientRecord pcr = new ProviderClientRecord(
4804 auths, provider, localProvider, holder);
4805 for (String auth : auths) {
4806 final ProviderKey key = new ProviderKey(auth, userId);
4807 final ProviderClientRecord existing = mProviderMap.get(key);
4808 if (existing != null) {
4809 Slog.w(TAG, "Content provider " + pcr.mHolder.info.name
4810 + " already published as " + auth);
4812 mProviderMap.put(key, pcr);
4819 * Installs the provider.
4821 * Providers that are local to the process or that come from the system server
4822 * may be installed permanently which is indicated by setting noReleaseNeeded to true.
4823 * Other remote providers are reference counted. The initial reference count
4824 * for all reference counted providers is one. Providers that are not reference
4825 * counted do not have a reference count (at all).
4827 * This method detects when a provider has already been installed. When this happens,
4828 * it increments the reference count of the existing provider (if appropriate)
4829 * and returns the existing provider. This can happen due to concurrent
4830 * attempts to acquire the same provider.
4832 private IActivityManager.ContentProviderHolder installProvider(Context context,
4833 IActivityManager.ContentProviderHolder holder, ProviderInfo info,
4834 boolean noisy, boolean noReleaseNeeded, boolean stable) {
4835 ContentProvider localProvider = null;
4836 IContentProvider provider;
4837 if (holder == null || holder.provider == null) {
4838 if (DEBUG_PROVIDER || noisy) {
4839 Slog.d(TAG, "Loading provider " + info.authority + ": "
4843 ApplicationInfo ai = info.applicationInfo;
4844 if (context.getPackageName().equals(ai.packageName)) {
4846 } else if (mInitialApplication != null &&
4847 mInitialApplication.getPackageName().equals(ai.packageName)) {
4848 c = mInitialApplication;
4851 c = context.createPackageContext(ai.packageName,
4852 Context.CONTEXT_INCLUDE_CODE);
4853 } catch (PackageManager.NameNotFoundException e) {
4858 Slog.w(TAG, "Unable to get context for package " +
4860 " while loading content provider " +
4865 final java.lang.ClassLoader cl = c.getClassLoader();
4866 localProvider = (ContentProvider)cl.
4867 loadClass(info.name).newInstance();
4868 provider = localProvider.getIContentProvider();
4869 if (provider == null) {
4870 Slog.e(TAG, "Failed to instantiate class " +
4871 info.name + " from sourceDir " +
4872 info.applicationInfo.sourceDir);
4875 if (DEBUG_PROVIDER) Slog.v(
4876 TAG, "Instantiating local provider " + info.name);
4877 // XXX Need to create the correct context for this provider.
4878 localProvider.attachInfo(c, info);
4879 } catch (java.lang.Exception e) {
4880 if (!mInstrumentation.onException(null, e)) {
4881 throw new RuntimeException(
4882 "Unable to get provider " + info.name
4883 + ": " + e.toString(), e);
4888 provider = holder.provider;
4889 if (DEBUG_PROVIDER) Slog.v(TAG, "Installing external provider " + info.authority + ": "
4893 IActivityManager.ContentProviderHolder retHolder;
4895 synchronized (mProviderMap) {
4896 if (DEBUG_PROVIDER) Slog.v(TAG, "Checking to add " + provider
4897 + " / " + info.name);
4898 IBinder jBinder = provider.asBinder();
4899 if (localProvider != null) {
4900 ComponentName cname = new ComponentName(info.packageName, info.name);
4901 ProviderClientRecord pr = mLocalProvidersByName.get(cname);
4903 if (DEBUG_PROVIDER) {
4904 Slog.v(TAG, "installProvider: lost the race, "
4905 + "using existing local provider");
4907 provider = pr.mProvider;
4909 holder = new IActivityManager.ContentProviderHolder(info);
4910 holder.provider = provider;
4911 holder.noReleaseNeeded = true;
4912 pr = installProviderAuthoritiesLocked(provider, localProvider, holder);
4913 mLocalProviders.put(jBinder, pr);
4914 mLocalProvidersByName.put(cname, pr);
4916 retHolder = pr.mHolder;
4918 ProviderRefCount prc = mProviderRefCountMap.get(jBinder);
4920 if (DEBUG_PROVIDER) {
4921 Slog.v(TAG, "installProvider: lost the race, updating ref count");
4923 // We need to transfer our new reference to the existing
4924 // ref count, releasing the old one... but only if
4925 // release is needed (that is, it is not running in the
4927 if (!noReleaseNeeded) {
4928 incProviderRefLocked(prc, stable);
4930 ActivityManagerNative.getDefault().removeContentProvider(
4931 holder.connection, stable);
4932 } catch (RemoteException e) {
4933 //do nothing content provider object is dead any way
4937 ProviderClientRecord client = installProviderAuthoritiesLocked(
4938 provider, localProvider, holder);
4939 if (noReleaseNeeded) {
4940 prc = new ProviderRefCount(holder, client, 1000, 1000);
4943 ? new ProviderRefCount(holder, client, 1, 0)
4944 : new ProviderRefCount(holder, client, 0, 1);
4946 mProviderRefCountMap.put(jBinder, prc);
4948 retHolder = prc.holder;
4955 private void attach(boolean system) {
4956 sCurrentActivityThread = this;
4957 mSystemThread = system;
4959 ViewRootImpl.addFirstDrawHandler(new Runnable() {
4964 android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",
4965 UserHandle.myUserId());
4966 RuntimeInit.setApplicationObject(mAppThread.asBinder());
4967 IActivityManager mgr = ActivityManagerNative.getDefault();
4969 mgr.attachApplication(mAppThread);
4970 } catch (RemoteException ex) {
4974 // Don't set application object here -- if the system crashes,
4975 // we can't display an alert, we just want to die die die.
4976 android.ddm.DdmHandleAppName.setAppName("system_process",
4977 UserHandle.myUserId());
4979 mInstrumentation = new Instrumentation();
4980 ContextImpl context = new ContextImpl();
4981 context.init(getSystemContext().mPackageInfo, null, this);
4982 Application app = Instrumentation.newApplication(Application.class, context);
4983 mAllApplications.add(app);
4984 mInitialApplication = app;
4986 } catch (Exception e) {
4987 throw new RuntimeException(
4988 "Unable to instantiate Application():" + e.toString(), e);
4992 // add dropbox logging to libcore
4993 DropBox.setReporter(new DropBoxReporter());
4995 ViewRootImpl.addConfigCallback(new ComponentCallbacks2() {
4996 public void onConfigurationChanged(Configuration newConfig) {
4997 synchronized (mPackages) {
4998 // We need to apply this change to the resources
4999 // immediately, because upon returning the view
5000 // hierarchy will be informed about it.
5001 if (applyConfigurationToResourcesLocked(newConfig, null)) {
5002 // This actually changed the resources! Tell
5003 // everyone about it.
5004 if (mPendingConfiguration == null ||
5005 mPendingConfiguration.isOtherSeqNewer(newConfig)) {
5006 mPendingConfiguration = newConfig;
5008 queueOrSendMessage(H.CONFIGURATION_CHANGED, newConfig);
5013 public void onLowMemory() {
5015 public void onTrimMemory(int level) {
5020 public static ActivityThread systemMain() {
5021 HardwareRenderer.disable(true);
5022 ActivityThread thread = new ActivityThread();
5023 thread.attach(true);
5027 public final void installSystemProviders(List<ProviderInfo> providers) {
5028 if (providers != null) {
5029 installContentProviders(mInitialApplication, providers);
5033 public int getIntCoreSetting(String key, int defaultValue) {
5034 synchronized (mPackages) {
5035 if (mCoreSettings != null) {
5036 return mCoreSettings.getInt(key, defaultValue);
5038 return defaultValue;
5043 private static class EventLoggingReporter implements EventLogger.Reporter {
5045 public void report (int code, Object... list) {
5046 EventLog.writeEvent(code, list);
5050 private class DropBoxReporter implements DropBox.Reporter {
5052 private DropBoxManager dropBox;
5054 public DropBoxReporter() {
5055 dropBox = (DropBoxManager) getSystemContext().getSystemService(Context.DROPBOX_SERVICE);
5059 public void addData(String tag, byte[] data, int flags) {
5060 dropBox.addData(tag, data, flags);
5064 public void addText(String tag, String data) {
5065 dropBox.addText(tag, data);
5069 public static void main(String[] args) {
5070 SamplingProfilerIntegration.start();
5072 // CloseGuard defaults to true and can be quite spammy. We
5073 // disable it here, but selectively enable it later (via
5074 // StrictMode) on debug builds, but using DropBox, not logs.
5075 CloseGuard.setEnabled(false);
5077 Environment.initForCurrentUser();
5079 // Set the reporter for event logging in libcore
5080 EventLogger.setReporter(new EventLoggingReporter());
5082 Security.addProvider(new AndroidKeyStoreProvider());
5084 Process.setArgV0("<pre-initialized>");
5086 Looper.prepareMainLooper();
5088 ActivityThread thread = new ActivityThread();
5089 thread.attach(false);
5091 if (sMainThreadHandler == null) {
5092 sMainThreadHandler = thread.getHandler();
5098 Looper.myLooper().setMessageLogging(new
5099 LogPrinter(Log.DEBUG, "ActivityThread"));
5104 throw new RuntimeException("Main thread loop unexpectedly exited");