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.ProxyInfo;
50 import android.net.Uri;
51 import android.opengl.GLUtils;
52 import android.os.AsyncTask;
53 import android.os.Binder;
54 import android.os.Bundle;
55 import android.os.Debug;
56 import android.os.DropBoxManager;
57 import android.os.Environment;
58 import android.os.Handler;
59 import android.os.IBinder;
60 import android.os.Looper;
61 import android.os.Message;
62 import android.os.MessageQueue;
63 import android.os.ParcelFileDescriptor;
64 import android.os.PersistableBundle;
65 import android.os.Process;
66 import android.os.RemoteException;
67 import android.os.ServiceManager;
68 import android.os.StrictMode;
69 import android.os.SystemClock;
70 import android.os.SystemProperties;
71 import android.os.Trace;
72 import android.os.UserHandle;
73 import android.provider.Settings;
74 import android.util.AndroidRuntimeException;
75 import android.util.ArrayMap;
76 import android.util.DisplayMetrics;
77 import android.util.EventLog;
78 import android.util.Log;
79 import android.util.LogPrinter;
80 import android.util.Pair;
81 import android.util.PrintWriterPrinter;
82 import android.util.Slog;
83 import android.util.SuperNotCalledException;
84 import android.view.Display;
85 import android.view.HardwareRenderer;
86 import android.view.View;
87 import android.view.ViewDebug;
88 import android.view.ViewManager;
89 import android.view.ViewRootImpl;
90 import android.view.Window;
91 import android.view.WindowManager;
92 import android.view.WindowManagerGlobal;
93 import android.renderscript.RenderScript;
94 import android.security.AndroidKeyStoreProvider;
96 import com.android.internal.app.IVoiceInteractor;
97 import com.android.internal.os.BinderInternal;
98 import com.android.internal.os.RuntimeInit;
99 import com.android.internal.os.SamplingProfilerIntegration;
100 import com.android.internal.util.FastPrintWriter;
101 import com.android.org.conscrypt.OpenSSLSocketImpl;
102 import com.android.org.conscrypt.TrustedCertificateStore;
103 import com.google.android.collect.Lists;
106 import java.io.FileDescriptor;
107 import java.io.FileOutputStream;
108 import java.io.IOException;
109 import java.io.PrintWriter;
110 import java.lang.ref.WeakReference;
111 import java.net.InetAddress;
112 import java.security.Security;
113 import java.text.DateFormat;
114 import java.util.ArrayList;
115 import java.util.List;
116 import java.util.Locale;
117 import java.util.Map;
118 import java.util.Objects;
119 import java.util.TimeZone;
120 import java.util.regex.Pattern;
122 import libcore.io.DropBox;
123 import libcore.io.EventLogger;
124 import libcore.io.IoUtils;
125 import libcore.net.event.NetworkEventDispatcher;
126 import dalvik.system.CloseGuard;
127 import dalvik.system.VMDebug;
128 import dalvik.system.VMRuntime;
130 final class RemoteServiceException extends AndroidRuntimeException {
131 public RemoteServiceException(String msg) {
137 * This manages the execution of the main thread in an
138 * application process, scheduling and executing activities,
139 * broadcasts, and other operations on it as the activity
144 public final class ActivityThread {
146 public static final String TAG = "ActivityThread";
147 private static final android.graphics.Bitmap.Config THUMBNAIL_FORMAT = Bitmap.Config.RGB_565;
148 static final boolean localLOGV = false;
149 static final boolean DEBUG_MESSAGES = false;
151 public static final boolean DEBUG_BROADCAST = false;
152 private static final boolean DEBUG_RESULTS = false;
153 private static final boolean DEBUG_BACKUP = false;
154 public static final boolean DEBUG_CONFIGURATION = false;
155 private static final boolean DEBUG_SERVICE = false;
156 private static final boolean DEBUG_MEMORY_TRIM = false;
157 private static final boolean DEBUG_PROVIDER = false;
158 private static final long MIN_TIME_BETWEEN_GCS = 5*1000;
159 private static final Pattern PATTERN_SEMICOLON = Pattern.compile(";");
160 private static final int SQLITE_MEM_RELEASED_EVENT_LOG_TAG = 75003;
161 private static final int LOG_ON_PAUSE_CALLED = 30021;
162 private static final int LOG_ON_RESUME_CALLED = 30022;
164 private ContextImpl mSystemContext;
166 static IPackageManager sPackageManager;
168 final ApplicationThread mAppThread = new ApplicationThread();
169 final Looper mLooper = Looper.myLooper();
170 final H mH = new H();
171 final ArrayMap<IBinder, ActivityClientRecord> mActivities
172 = new ArrayMap<IBinder, ActivityClientRecord>();
173 // List of new activities (via ActivityRecord.nextIdle) that should
174 // be reported when next we idle.
175 ActivityClientRecord mNewActivities = null;
176 // Number of activities that are currently visible on-screen.
177 int mNumVisibleActivities = 0;
178 final ArrayMap<IBinder, Service> mServices
179 = new ArrayMap<IBinder, Service>();
180 AppBindData mBoundApplication;
182 int mCurDefaultDisplayDpi;
183 boolean mDensityCompatMode;
184 Configuration mConfiguration;
185 Configuration mCompatConfiguration;
186 Application mInitialApplication;
187 final ArrayList<Application> mAllApplications
188 = new ArrayList<Application>();
189 // set of instantiated backup agents, keyed by package name
190 final ArrayMap<String, BackupAgent> mBackupAgents = new ArrayMap<String, BackupAgent>();
191 /** Reference to singleton {@link ActivityThread} */
192 private static ActivityThread sCurrentActivityThread;
193 Instrumentation mInstrumentation;
194 String mInstrumentationPackageName = null;
195 String mInstrumentationAppDir = null;
196 String[] mInstrumentationSplitAppDirs = null;
197 String mInstrumentationLibDir = null;
198 String mInstrumentedAppDir = null;
199 String[] mInstrumentedSplitAppDirs = null;
200 String mInstrumentedLibDir = null;
201 boolean mSystemThread = false;
202 boolean mJitEnabled = false;
203 boolean mSomeActivitiesChanged = false;
205 // These can be accessed by multiple threads; mPackages is the lock.
206 // XXX For now we keep around information about all packages we have
207 // seen, not removing entries from this map.
208 // NOTE: The activity and window managers need to call in to
209 // ActivityThread to do things like update resource configurations,
210 // which means this lock gets held while the activity and window managers
211 // holds their own lock. Thus you MUST NEVER call back into the activity manager
212 // or window manager or anything that depends on them while holding this lock.
213 final ArrayMap<String, WeakReference<LoadedApk>> mPackages
214 = new ArrayMap<String, WeakReference<LoadedApk>>();
215 final ArrayMap<String, WeakReference<LoadedApk>> mResourcePackages
216 = new ArrayMap<String, WeakReference<LoadedApk>>();
217 final ArrayList<ActivityClientRecord> mRelaunchingActivities
218 = new ArrayList<ActivityClientRecord>();
219 Configuration mPendingConfiguration = null;
221 private final ResourcesManager mResourcesManager;
223 private static final class ProviderKey {
224 final String authority;
227 public ProviderKey(String authority, int userId) {
228 this.authority = authority;
229 this.userId = userId;
233 public boolean equals(Object o) {
234 if (o instanceof ProviderKey) {
235 final ProviderKey other = (ProviderKey) o;
236 return Objects.equals(authority, other.authority) && userId == other.userId;
242 public int hashCode() {
243 return ((authority != null) ? authority.hashCode() : 0) ^ userId;
247 // The lock of mProviderMap protects the following variables.
248 final ArrayMap<ProviderKey, ProviderClientRecord> mProviderMap
249 = new ArrayMap<ProviderKey, ProviderClientRecord>();
250 final ArrayMap<IBinder, ProviderRefCount> mProviderRefCountMap
251 = new ArrayMap<IBinder, ProviderRefCount>();
252 final ArrayMap<IBinder, ProviderClientRecord> mLocalProviders
253 = new ArrayMap<IBinder, ProviderClientRecord>();
254 final ArrayMap<ComponentName, ProviderClientRecord> mLocalProvidersByName
255 = new ArrayMap<ComponentName, ProviderClientRecord>();
257 final ArrayMap<Activity, ArrayList<OnActivityPausedListener>> mOnPauseListeners
258 = new ArrayMap<Activity, ArrayList<OnActivityPausedListener>>();
260 final GcIdler mGcIdler = new GcIdler();
261 boolean mGcIdlerScheduled = false;
263 static Handler sMainThreadHandler; // set once in main()
265 Bundle mCoreSettings = null;
267 static final class ActivityClientRecord {
271 IVoiceInteractor voiceInteractor;
273 PersistableBundle persistentState;
278 Activity.NonConfigurationInstances lastNonConfigurationInstances;
282 Configuration newConfig;
283 Configuration createdConfig;
284 ActivityClientRecord nextIdle;
286 ProfilerInfo profilerInfo;
288 ActivityInfo activityInfo;
289 CompatibilityInfo compatInfo;
290 LoadedApk packageInfo;
292 List<ResultInfo> pendingResults;
293 List<Intent> pendingIntents;
295 boolean startsNotResumed;
297 int pendingConfigChanges;
298 boolean onlyLocalRequest;
300 View mPendingRemoveWindow;
301 WindowManager mPendingRemoveWindowManager;
303 ActivityClientRecord() {
312 public boolean isPreHoneycomb() {
313 if (activity != null) {
314 return activity.getApplicationInfo().targetSdkVersion
315 < android.os.Build.VERSION_CODES.HONEYCOMB;
320 public boolean isPersistable() {
321 return activityInfo.persistableMode == ActivityInfo.PERSIST_ACROSS_REBOOTS;
324 public String toString() {
325 ComponentName componentName = intent != null ? intent.getComponent() : null;
326 return "ActivityRecord{"
327 + Integer.toHexString(System.identityHashCode(this))
328 + " token=" + token + " " + (componentName == null
329 ? "no component name" : componentName.toShortString())
334 final class ProviderClientRecord {
335 final String[] mNames;
336 final IContentProvider mProvider;
337 final ContentProvider mLocalProvider;
338 final IActivityManager.ContentProviderHolder mHolder;
340 ProviderClientRecord(String[] names, IContentProvider provider,
341 ContentProvider localProvider,
342 IActivityManager.ContentProviderHolder holder) {
344 mProvider = provider;
345 mLocalProvider = localProvider;
350 static final class NewIntentData {
351 List<Intent> intents;
353 public String toString() {
354 return "NewIntentData{intents=" + intents + " token=" + token + "}";
358 static final class ReceiverData extends BroadcastReceiver.PendingResult {
359 public ReceiverData(Intent intent, int resultCode, String resultData, Bundle resultExtras,
360 boolean ordered, boolean sticky, IBinder token, int sendingUser) {
361 super(resultCode, resultData, resultExtras, TYPE_COMPONENT, ordered, sticky,
363 this.intent = intent;
368 CompatibilityInfo compatInfo;
369 public String toString() {
370 return "ReceiverData{intent=" + intent + " packageName=" +
371 info.packageName + " resultCode=" + getResultCode()
372 + " resultData=" + getResultData() + " resultExtras="
373 + getResultExtras(false) + "}";
377 static final class CreateBackupAgentData {
378 ApplicationInfo appInfo;
379 CompatibilityInfo compatInfo;
381 public String toString() {
382 return "CreateBackupAgentData{appInfo=" + appInfo
383 + " backupAgent=" + appInfo.backupAgentName
384 + " mode=" + backupMode + "}";
388 static final class CreateServiceData {
391 CompatibilityInfo compatInfo;
393 public String toString() {
394 return "CreateServiceData{token=" + token + " className="
395 + info.name + " packageName=" + info.packageName
396 + " intent=" + intent + "}";
400 static final class BindServiceData {
404 public String toString() {
405 return "BindServiceData{token=" + token + " intent=" + intent + "}";
409 static final class ServiceArgsData {
415 public String toString() {
416 return "ServiceArgsData{token=" + token + " startId=" + startId
417 + " args=" + args + "}";
421 static final class AppBindData {
424 ApplicationInfo appInfo;
425 List<ProviderInfo> providers;
426 ComponentName instrumentationName;
427 Bundle instrumentationArgs;
428 IInstrumentationWatcher instrumentationWatcher;
429 IUiAutomationConnection instrumentationUiAutomationConnection;
431 boolean enableOpenGlTrace;
432 boolean restrictedBackupMode;
434 Configuration config;
435 CompatibilityInfo compatInfo;
437 /** Initial values for {@link Profiler}. */
438 ProfilerInfo initProfilerInfo;
440 public String toString() {
441 return "AppBindData{appInfo=" + appInfo + "}";
445 static final class Profiler {
447 ParcelFileDescriptor profileFd;
448 int samplingInterval;
449 boolean autoStopProfiler;
451 boolean handlingProfiling;
452 public void setProfiler(ProfilerInfo profilerInfo) {
453 ParcelFileDescriptor fd = profilerInfo.profileFd;
458 } catch (IOException e) {
464 if (profileFd != null) {
467 } catch (IOException e) {
471 profileFile = profilerInfo.profileFile;
473 samplingInterval = profilerInfo.samplingInterval;
474 autoStopProfiler = profilerInfo.autoStopProfiler;
476 public void startProfiling() {
477 if (profileFd == null || profiling) {
481 VMDebug.startMethodTracing(profileFile, profileFd.getFileDescriptor(),
482 8 * 1024 * 1024, 0, samplingInterval != 0, samplingInterval);
484 } catch (RuntimeException e) {
485 Slog.w(TAG, "Profiling failed on path " + profileFile);
489 } catch (IOException e2) {
490 Slog.w(TAG, "Failure closing profile fd", e2);
494 public void stopProfiling() {
497 Debug.stopMethodTracing();
498 if (profileFd != null) {
501 } catch (IOException e) {
510 static final class DumpComponentInfo {
511 ParcelFileDescriptor fd;
517 static final class ResultData {
519 List<ResultInfo> results;
520 public String toString() {
521 return "ResultData{token=" + token + " results" + results + "}";
525 static final class ContextCleanupInfo {
531 static final class DumpHeapData {
533 ParcelFileDescriptor fd;
536 static final class UpdateCompatibilityData {
538 CompatibilityInfo info;
541 static final class RequestAssistContextExtras {
542 IBinder activityToken;
543 IBinder requestToken;
547 private native void dumpGraphicsInfo(FileDescriptor fd);
549 private class ApplicationThread extends ApplicationThreadNative {
550 private static final String ONE_COUNT_COLUMN = "%21s %8d";
551 private static final String TWO_COUNT_COLUMNS = "%21s %8d %21s %8d";
552 private static final String DB_INFO_FORMAT = " %8s %8s %14s %14s %s";
554 private int mLastProcessState = -1;
556 private void updatePendingConfiguration(Configuration config) {
557 synchronized (mResourcesManager) {
558 if (mPendingConfiguration == null ||
559 mPendingConfiguration.isOtherSeqNewer(config)) {
560 mPendingConfiguration = config;
565 public final void schedulePauseActivity(IBinder token, boolean finished,
566 boolean userLeaving, int configChanges, boolean dontReport) {
568 finished ? H.PAUSE_ACTIVITY_FINISHING : H.PAUSE_ACTIVITY,
570 (userLeaving ? 1 : 0) | (dontReport ? 2 : 0),
574 public final void scheduleStopActivity(IBinder token, boolean showWindow,
577 showWindow ? H.STOP_ACTIVITY_SHOW : H.STOP_ACTIVITY_HIDE,
578 token, 0, configChanges);
581 public final void scheduleWindowVisibility(IBinder token, boolean showWindow) {
583 showWindow ? H.SHOW_WINDOW : H.HIDE_WINDOW,
587 public final void scheduleSleeping(IBinder token, boolean sleeping) {
588 sendMessage(H.SLEEPING, token, sleeping ? 1 : 0);
591 public final void scheduleResumeActivity(IBinder token, int processState,
592 boolean isForward, Bundle resumeArgs) {
593 updateProcessState(processState, false);
594 sendMessage(H.RESUME_ACTIVITY, token, isForward ? 1 : 0);
597 public final void scheduleSendResult(IBinder token, List<ResultInfo> results) {
598 ResultData res = new ResultData();
600 res.results = results;
601 sendMessage(H.SEND_RESULT, res);
604 // we use token to identify this activity without having to send the
605 // activity itself back to the activity manager. (matters more with ipc)
606 public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
607 ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo,
608 IVoiceInteractor voiceInteractor, int procState, Bundle state,
609 PersistableBundle persistentState, List<ResultInfo> pendingResults,
610 List<Intent> pendingNewIntents, boolean notResumed, boolean isForward,
611 ProfilerInfo profilerInfo) {
613 updateProcessState(procState, false);
615 ActivityClientRecord r = new ActivityClientRecord();
620 r.voiceInteractor = voiceInteractor;
621 r.activityInfo = info;
622 r.compatInfo = compatInfo;
624 r.persistentState = persistentState;
626 r.pendingResults = pendingResults;
627 r.pendingIntents = pendingNewIntents;
629 r.startsNotResumed = notResumed;
630 r.isForward = isForward;
632 r.profilerInfo = profilerInfo;
634 updatePendingConfiguration(curConfig);
636 sendMessage(H.LAUNCH_ACTIVITY, r);
639 public final void scheduleRelaunchActivity(IBinder token,
640 List<ResultInfo> pendingResults, List<Intent> pendingNewIntents,
641 int configChanges, boolean notResumed, Configuration config) {
642 requestRelaunchActivity(token, pendingResults, pendingNewIntents,
643 configChanges, notResumed, config, true);
646 public final void scheduleNewIntent(List<Intent> intents, IBinder token) {
647 NewIntentData data = new NewIntentData();
648 data.intents = intents;
651 sendMessage(H.NEW_INTENT, data);
654 public final void scheduleDestroyActivity(IBinder token, boolean finishing,
656 sendMessage(H.DESTROY_ACTIVITY, token, finishing ? 1 : 0,
660 public final void scheduleReceiver(Intent intent, ActivityInfo info,
661 CompatibilityInfo compatInfo, int resultCode, String data, Bundle extras,
662 boolean sync, int sendingUser, int processState) {
663 updateProcessState(processState, false);
664 ReceiverData r = new ReceiverData(intent, resultCode, data, extras,
665 sync, false, mAppThread.asBinder(), sendingUser);
667 r.compatInfo = compatInfo;
668 sendMessage(H.RECEIVER, r);
671 public final void scheduleCreateBackupAgent(ApplicationInfo app,
672 CompatibilityInfo compatInfo, int backupMode) {
673 CreateBackupAgentData d = new CreateBackupAgentData();
675 d.compatInfo = compatInfo;
676 d.backupMode = backupMode;
678 sendMessage(H.CREATE_BACKUP_AGENT, d);
681 public final void scheduleDestroyBackupAgent(ApplicationInfo app,
682 CompatibilityInfo compatInfo) {
683 CreateBackupAgentData d = new CreateBackupAgentData();
685 d.compatInfo = compatInfo;
687 sendMessage(H.DESTROY_BACKUP_AGENT, d);
690 public final void scheduleCreateService(IBinder token,
691 ServiceInfo info, CompatibilityInfo compatInfo, int processState) {
692 updateProcessState(processState, false);
693 CreateServiceData s = new CreateServiceData();
696 s.compatInfo = compatInfo;
698 sendMessage(H.CREATE_SERVICE, s);
701 public final void scheduleBindService(IBinder token, Intent intent,
702 boolean rebind, int processState) {
703 updateProcessState(processState, false);
704 BindServiceData s = new BindServiceData();
710 Slog.v(TAG, "scheduleBindService token=" + token + " intent=" + intent + " uid="
711 + Binder.getCallingUid() + " pid=" + Binder.getCallingPid());
712 sendMessage(H.BIND_SERVICE, s);
715 public final void scheduleUnbindService(IBinder token, Intent intent) {
716 BindServiceData s = new BindServiceData();
720 sendMessage(H.UNBIND_SERVICE, s);
723 public final void scheduleServiceArgs(IBinder token, boolean taskRemoved, int startId,
724 int flags ,Intent args) {
725 ServiceArgsData s = new ServiceArgsData();
727 s.taskRemoved = taskRemoved;
732 sendMessage(H.SERVICE_ARGS, s);
735 public final void scheduleStopService(IBinder token) {
736 sendMessage(H.STOP_SERVICE, token);
739 public final void bindApplication(String processName, ApplicationInfo appInfo,
740 List<ProviderInfo> providers, ComponentName instrumentationName,
741 ProfilerInfo profilerInfo, Bundle instrumentationArgs,
742 IInstrumentationWatcher instrumentationWatcher,
743 IUiAutomationConnection instrumentationUiConnection, int debugMode,
744 boolean enableOpenGlTrace, boolean isRestrictedBackupMode, boolean persistent,
745 Configuration config, CompatibilityInfo compatInfo, Map<String, IBinder> services,
746 Bundle coreSettings) {
748 if (services != null) {
749 // Setup the service cache in the ServiceManager
750 ServiceManager.initServiceCache(services);
753 setCoreSettings(coreSettings);
756 * Two possible indications that this package could be
757 * sharing its runtime with other packages:
759 * 1.) the sharedUserId attribute is set in the manifest,
760 * indicating a request to share a VM with other
761 * packages with the same sharedUserId.
763 * 2.) the application element of the manifest has an
764 * attribute specifying a non-default process name,
765 * indicating the desire to run in another packages VM.
767 * If sharing is enabled we do not have a unique application
768 * in a process and therefore cannot rely on the package
769 * name inside the runtime.
771 IPackageManager pm = getPackageManager();
772 android.content.pm.PackageInfo pi = null;
774 pi = pm.getPackageInfo(appInfo.packageName, 0, UserHandle.myUserId());
775 } catch (RemoteException e) {
778 boolean sharedUserIdSet = (pi.sharedUserId != null);
779 boolean processNameNotDefault =
780 (pi.applicationInfo != null &&
781 !appInfo.packageName.equals(pi.applicationInfo.processName));
782 boolean sharable = (sharedUserIdSet || processNameNotDefault);
784 // Tell the VMRuntime about the application, unless it is shared
787 VMRuntime.registerAppInfo(appInfo.packageName, appInfo.dataDir,
788 appInfo.processName);
792 AppBindData data = new AppBindData();
793 data.processName = processName;
794 data.appInfo = appInfo;
795 data.providers = providers;
796 data.instrumentationName = instrumentationName;
797 data.instrumentationArgs = instrumentationArgs;
798 data.instrumentationWatcher = instrumentationWatcher;
799 data.instrumentationUiAutomationConnection = instrumentationUiConnection;
800 data.debugMode = debugMode;
801 data.enableOpenGlTrace = enableOpenGlTrace;
802 data.restrictedBackupMode = isRestrictedBackupMode;
803 data.persistent = persistent;
804 data.config = config;
805 data.compatInfo = compatInfo;
806 data.initProfilerInfo = profilerInfo;
807 sendMessage(H.BIND_APPLICATION, data);
810 public final void scheduleExit() {
811 sendMessage(H.EXIT_APPLICATION, null);
814 public final void scheduleSuicide() {
815 sendMessage(H.SUICIDE, null);
818 public void scheduleConfigurationChanged(Configuration config) {
819 updatePendingConfiguration(config);
820 sendMessage(H.CONFIGURATION_CHANGED, config);
823 public void updateTimeZone() {
824 TimeZone.setDefault(null);
827 public void clearDnsCache() {
828 // a non-standard API to get this to libcore
829 InetAddress.clearDnsCache();
830 // Allow libcore to perform the necessary actions as it sees fit upon a network
831 // configuration change.
832 NetworkEventDispatcher.getInstance().onNetworkConfigurationChanged();
835 public void setHttpProxy(String host, String port, String exclList, Uri pacFileUrl) {
836 Proxy.setHttpProxySystemProperty(host, port, exclList, pacFileUrl);
839 public void processInBackground() {
840 mH.removeMessages(H.GC_WHEN_IDLE);
841 mH.sendMessage(mH.obtainMessage(H.GC_WHEN_IDLE));
844 public void dumpService(FileDescriptor fd, IBinder servicetoken, String[] args) {
845 DumpComponentInfo data = new DumpComponentInfo();
847 data.fd = ParcelFileDescriptor.dup(fd);
848 data.token = servicetoken;
850 sendMessage(H.DUMP_SERVICE, data, 0, 0, true /*async*/);
851 } catch (IOException e) {
852 Slog.w(TAG, "dumpService failed", e);
856 // This function exists to make sure all receiver dispatching is
857 // correctly ordered, since these are one-way calls and the binder driver
858 // applies transaction ordering per object for such calls.
859 public void scheduleRegisteredReceiver(IIntentReceiver receiver, Intent intent,
860 int resultCode, String dataStr, Bundle extras, boolean ordered,
861 boolean sticky, int sendingUser, int processState) throws RemoteException {
862 updateProcessState(processState, false);
863 receiver.performReceive(intent, resultCode, dataStr, extras, ordered,
864 sticky, sendingUser);
867 public void scheduleLowMemory() {
868 sendMessage(H.LOW_MEMORY, null);
871 public void scheduleActivityConfigurationChanged(IBinder token) {
872 sendMessage(H.ACTIVITY_CONFIGURATION_CHANGED, token);
875 public void profilerControl(boolean start, ProfilerInfo profilerInfo, int profileType) {
876 sendMessage(H.PROFILER_CONTROL, profilerInfo, start ? 1 : 0, profileType);
879 public void dumpHeap(boolean managed, String path, ParcelFileDescriptor fd) {
880 DumpHeapData dhd = new DumpHeapData();
883 sendMessage(H.DUMP_HEAP, dhd, managed ? 1 : 0, 0, true /*async*/);
886 public void setSchedulingGroup(int group) {
887 // Note: do this immediately, since going into the foreground
888 // should happen regardless of what pending work we have to do
889 // and the activity manager will wait for us to report back that
890 // we are done before sending us to the background.
892 Process.setProcessGroup(Process.myPid(), group);
893 } catch (Exception e) {
894 Slog.w(TAG, "Failed setting process group to " + group, e);
898 public void dispatchPackageBroadcast(int cmd, String[] packages) {
899 sendMessage(H.DISPATCH_PACKAGE_BROADCAST, packages, cmd);
902 public void scheduleCrash(String msg) {
903 sendMessage(H.SCHEDULE_CRASH, msg);
906 public void dumpActivity(FileDescriptor fd, IBinder activitytoken,
907 String prefix, String[] args) {
908 DumpComponentInfo data = new DumpComponentInfo();
910 data.fd = ParcelFileDescriptor.dup(fd);
911 data.token = activitytoken;
912 data.prefix = prefix;
914 sendMessage(H.DUMP_ACTIVITY, data, 0, 0, true /*async*/);
915 } catch (IOException e) {
916 Slog.w(TAG, "dumpActivity failed", e);
920 public void dumpProvider(FileDescriptor fd, IBinder providertoken,
922 DumpComponentInfo data = new DumpComponentInfo();
924 data.fd = ParcelFileDescriptor.dup(fd);
925 data.token = providertoken;
927 sendMessage(H.DUMP_PROVIDER, data, 0, 0, true /*async*/);
928 } catch (IOException e) {
929 Slog.w(TAG, "dumpProvider failed", e);
934 public void dumpMemInfo(FileDescriptor fd, Debug.MemoryInfo mem, boolean checkin,
935 boolean dumpFullInfo, boolean dumpDalvik, String[] args) {
936 FileOutputStream fout = new FileOutputStream(fd);
937 PrintWriter pw = new FastPrintWriter(fout);
939 dumpMemInfo(pw, mem, checkin, dumpFullInfo, dumpDalvik);
945 private void dumpMemInfo(PrintWriter pw, Debug.MemoryInfo memInfo, boolean checkin,
946 boolean dumpFullInfo, boolean dumpDalvik) {
947 long nativeMax = Debug.getNativeHeapSize() / 1024;
948 long nativeAllocated = Debug.getNativeHeapAllocatedSize() / 1024;
949 long nativeFree = Debug.getNativeHeapFreeSize() / 1024;
951 Runtime runtime = Runtime.getRuntime();
953 long dalvikMax = runtime.totalMemory() / 1024;
954 long dalvikFree = runtime.freeMemory() / 1024;
955 long dalvikAllocated = dalvikMax - dalvikFree;
956 long viewInstanceCount = ViewDebug.getViewInstanceCount();
957 long viewRootInstanceCount = ViewDebug.getViewRootImplCount();
958 long appContextInstanceCount = Debug.countInstancesOfClass(ContextImpl.class);
959 long activityInstanceCount = Debug.countInstancesOfClass(Activity.class);
960 int globalAssetCount = AssetManager.getGlobalAssetCount();
961 int globalAssetManagerCount = AssetManager.getGlobalAssetManagerCount();
962 int binderLocalObjectCount = Debug.getBinderLocalObjectCount();
963 int binderProxyObjectCount = Debug.getBinderProxyObjectCount();
964 int binderDeathObjectCount = Debug.getBinderDeathObjectCount();
965 long openSslSocketCount = Debug.countInstancesOfClass(OpenSSLSocketImpl.class);
966 SQLiteDebug.PagerStats stats = SQLiteDebug.getDatabaseInfo();
968 dumpMemInfoTable(pw, memInfo, checkin, dumpFullInfo, dumpDalvik, Process.myPid(),
969 (mBoundApplication != null) ? mBoundApplication.processName : "unknown",
970 nativeMax, nativeAllocated, nativeFree,
971 dalvikMax, dalvikAllocated, dalvikFree);
974 // NOTE: if you change anything significant below, also consider changing
975 // ACTIVITY_THREAD_CHECKIN_VERSION.
978 pw.print(viewInstanceCount); pw.print(',');
979 pw.print(viewRootInstanceCount); pw.print(',');
980 pw.print(appContextInstanceCount); pw.print(',');
981 pw.print(activityInstanceCount); pw.print(',');
983 pw.print(globalAssetCount); pw.print(',');
984 pw.print(globalAssetManagerCount); pw.print(',');
985 pw.print(binderLocalObjectCount); pw.print(',');
986 pw.print(binderProxyObjectCount); pw.print(',');
988 pw.print(binderDeathObjectCount); pw.print(',');
989 pw.print(openSslSocketCount); pw.print(',');
992 pw.print(stats.memoryUsed / 1024); pw.print(',');
993 pw.print(stats.memoryUsed / 1024); pw.print(',');
994 pw.print(stats.pageCacheOverflow / 1024); pw.print(',');
995 pw.print(stats.largestMemAlloc / 1024);
996 for (int i = 0; i < stats.dbStats.size(); i++) {
997 DbStats dbStats = stats.dbStats.get(i);
998 pw.print(','); pw.print(dbStats.dbName);
999 pw.print(','); pw.print(dbStats.pageSize);
1000 pw.print(','); pw.print(dbStats.dbSize);
1001 pw.print(','); pw.print(dbStats.lookaside);
1002 pw.print(','); pw.print(dbStats.cache);
1003 pw.print(','); pw.print(dbStats.cache);
1011 pw.println(" Objects");
1012 printRow(pw, TWO_COUNT_COLUMNS, "Views:", viewInstanceCount, "ViewRootImpl:",
1013 viewRootInstanceCount);
1015 printRow(pw, TWO_COUNT_COLUMNS, "AppContexts:", appContextInstanceCount,
1016 "Activities:", activityInstanceCount);
1018 printRow(pw, TWO_COUNT_COLUMNS, "Assets:", globalAssetCount,
1019 "AssetManagers:", globalAssetManagerCount);
1021 printRow(pw, TWO_COUNT_COLUMNS, "Local Binders:", binderLocalObjectCount,
1022 "Proxy Binders:", binderProxyObjectCount);
1023 printRow(pw, ONE_COUNT_COLUMN, "Death Recipients:", binderDeathObjectCount);
1025 printRow(pw, ONE_COUNT_COLUMN, "OpenSSL Sockets:", openSslSocketCount);
1030 printRow(pw, ONE_COUNT_COLUMN, "MEMORY_USED:", stats.memoryUsed / 1024);
1031 printRow(pw, TWO_COUNT_COLUMNS, "PAGECACHE_OVERFLOW:",
1032 stats.pageCacheOverflow / 1024, "MALLOC_SIZE:", stats.largestMemAlloc / 1024);
1034 int N = stats.dbStats.size();
1036 pw.println(" DATABASES");
1037 printRow(pw, " %8s %8s %14s %14s %s", "pgsz", "dbsz", "Lookaside(b)", "cache",
1039 for (int i = 0; i < N; i++) {
1040 DbStats dbStats = stats.dbStats.get(i);
1041 printRow(pw, DB_INFO_FORMAT,
1042 (dbStats.pageSize > 0) ? String.valueOf(dbStats.pageSize) : " ",
1043 (dbStats.dbSize > 0) ? String.valueOf(dbStats.dbSize) : " ",
1044 (dbStats.lookaside > 0) ? String.valueOf(dbStats.lookaside) : " ",
1045 dbStats.cache, dbStats.dbName);
1050 String assetAlloc = AssetManager.getAssetAllocations();
1051 if (assetAlloc != null) {
1053 pw.println(" Asset Allocations");
1054 pw.print(assetAlloc);
1059 public void dumpGfxInfo(FileDescriptor fd, String[] args) {
1060 dumpGraphicsInfo(fd);
1061 WindowManagerGlobal.getInstance().dumpGfxInfo(fd);
1065 public void dumpDbInfo(FileDescriptor fd, String[] args) {
1066 PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd));
1067 PrintWriterPrinter printer = new PrintWriterPrinter(pw);
1068 SQLiteDebug.dump(printer, args);
1073 public void unstableProviderDied(IBinder provider) {
1074 sendMessage(H.UNSTABLE_PROVIDER_DIED, provider);
1078 public void requestAssistContextExtras(IBinder activityToken, IBinder requestToken,
1080 RequestAssistContextExtras cmd = new RequestAssistContextExtras();
1081 cmd.activityToken = activityToken;
1082 cmd.requestToken = requestToken;
1083 cmd.requestType = requestType;
1084 sendMessage(H.REQUEST_ASSIST_CONTEXT_EXTRAS, cmd);
1087 public void setCoreSettings(Bundle coreSettings) {
1088 sendMessage(H.SET_CORE_SETTINGS, coreSettings);
1091 public void updatePackageCompatibilityInfo(String pkg, CompatibilityInfo info) {
1092 UpdateCompatibilityData ucd = new UpdateCompatibilityData();
1095 sendMessage(H.UPDATE_PACKAGE_COMPATIBILITY_INFO, ucd);
1098 public void scheduleTrimMemory(int level) {
1099 sendMessage(H.TRIM_MEMORY, null, level);
1102 public void scheduleTranslucentConversionComplete(IBinder token, boolean drawComplete) {
1103 sendMessage(H.TRANSLUCENT_CONVERSION_COMPLETE, token, drawComplete ? 1 : 0);
1106 public void scheduleOnNewActivityOptions(IBinder token, ActivityOptions options) {
1107 sendMessage(H.ON_NEW_ACTIVITY_OPTIONS,
1108 new Pair<IBinder, ActivityOptions>(token, options));
1111 public void setProcessState(int state) {
1112 updateProcessState(state, true);
1115 public void updateProcessState(int processState, boolean fromIpc) {
1116 synchronized (this) {
1117 if (mLastProcessState != processState) {
1118 mLastProcessState = processState;
1119 // Update Dalvik state based on ActivityManager.PROCESS_STATE_* constants.
1120 final int DALVIK_PROCESS_STATE_JANK_PERCEPTIBLE = 0;
1121 final int DALVIK_PROCESS_STATE_JANK_IMPERCEPTIBLE = 1;
1122 int dalvikProcessState = DALVIK_PROCESS_STATE_JANK_IMPERCEPTIBLE;
1123 // TODO: Tune this since things like gmail sync are important background but not jank perceptible.
1124 if (processState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
1125 dalvikProcessState = DALVIK_PROCESS_STATE_JANK_PERCEPTIBLE;
1127 VMRuntime.getRuntime().updateProcessState(dalvikProcessState);
1129 Slog.i(TAG, "******************* PROCESS STATE CHANGED TO: " + processState
1130 + (fromIpc ? " (from ipc": ""));
1137 public void scheduleInstallProvider(ProviderInfo provider) {
1138 sendMessage(H.INSTALL_PROVIDER, provider);
1142 public final void updateTimePrefs(boolean is24Hour) {
1143 DateFormat.set24HourTimePref(is24Hour);
1147 public void scheduleCancelVisibleBehind(IBinder token) {
1148 sendMessage(H.CANCEL_VISIBLE_BEHIND, token);
1152 public void scheduleBackgroundVisibleBehindChanged(IBinder token, boolean visible) {
1153 sendMessage(H.BACKGROUND_VISIBLE_BEHIND_CHANGED, token, visible ? 1 : 0);
1156 public void scheduleEnterAnimationComplete(IBinder token) {
1157 sendMessage(H.ENTER_ANIMATION_COMPLETE, token);
1161 private class H extends Handler {
1162 public static final int LAUNCH_ACTIVITY = 100;
1163 public static final int PAUSE_ACTIVITY = 101;
1164 public static final int PAUSE_ACTIVITY_FINISHING= 102;
1165 public static final int STOP_ACTIVITY_SHOW = 103;
1166 public static final int STOP_ACTIVITY_HIDE = 104;
1167 public static final int SHOW_WINDOW = 105;
1168 public static final int HIDE_WINDOW = 106;
1169 public static final int RESUME_ACTIVITY = 107;
1170 public static final int SEND_RESULT = 108;
1171 public static final int DESTROY_ACTIVITY = 109;
1172 public static final int BIND_APPLICATION = 110;
1173 public static final int EXIT_APPLICATION = 111;
1174 public static final int NEW_INTENT = 112;
1175 public static final int RECEIVER = 113;
1176 public static final int CREATE_SERVICE = 114;
1177 public static final int SERVICE_ARGS = 115;
1178 public static final int STOP_SERVICE = 116;
1180 public static final int CONFIGURATION_CHANGED = 118;
1181 public static final int CLEAN_UP_CONTEXT = 119;
1182 public static final int GC_WHEN_IDLE = 120;
1183 public static final int BIND_SERVICE = 121;
1184 public static final int UNBIND_SERVICE = 122;
1185 public static final int DUMP_SERVICE = 123;
1186 public static final int LOW_MEMORY = 124;
1187 public static final int ACTIVITY_CONFIGURATION_CHANGED = 125;
1188 public static final int RELAUNCH_ACTIVITY = 126;
1189 public static final int PROFILER_CONTROL = 127;
1190 public static final int CREATE_BACKUP_AGENT = 128;
1191 public static final int DESTROY_BACKUP_AGENT = 129;
1192 public static final int SUICIDE = 130;
1193 public static final int REMOVE_PROVIDER = 131;
1194 public static final int ENABLE_JIT = 132;
1195 public static final int DISPATCH_PACKAGE_BROADCAST = 133;
1196 public static final int SCHEDULE_CRASH = 134;
1197 public static final int DUMP_HEAP = 135;
1198 public static final int DUMP_ACTIVITY = 136;
1199 public static final int SLEEPING = 137;
1200 public static final int SET_CORE_SETTINGS = 138;
1201 public static final int UPDATE_PACKAGE_COMPATIBILITY_INFO = 139;
1202 public static final int TRIM_MEMORY = 140;
1203 public static final int DUMP_PROVIDER = 141;
1204 public static final int UNSTABLE_PROVIDER_DIED = 142;
1205 public static final int REQUEST_ASSIST_CONTEXT_EXTRAS = 143;
1206 public static final int TRANSLUCENT_CONVERSION_COMPLETE = 144;
1207 public static final int INSTALL_PROVIDER = 145;
1208 public static final int ON_NEW_ACTIVITY_OPTIONS = 146;
1209 public static final int CANCEL_VISIBLE_BEHIND = 147;
1210 public static final int BACKGROUND_VISIBLE_BEHIND_CHANGED = 148;
1211 public static final int ENTER_ANIMATION_COMPLETE = 149;
1213 String codeToString(int code) {
1214 if (DEBUG_MESSAGES) {
1216 case LAUNCH_ACTIVITY: return "LAUNCH_ACTIVITY";
1217 case PAUSE_ACTIVITY: return "PAUSE_ACTIVITY";
1218 case PAUSE_ACTIVITY_FINISHING: return "PAUSE_ACTIVITY_FINISHING";
1219 case STOP_ACTIVITY_SHOW: return "STOP_ACTIVITY_SHOW";
1220 case STOP_ACTIVITY_HIDE: return "STOP_ACTIVITY_HIDE";
1221 case SHOW_WINDOW: return "SHOW_WINDOW";
1222 case HIDE_WINDOW: return "HIDE_WINDOW";
1223 case RESUME_ACTIVITY: return "RESUME_ACTIVITY";
1224 case SEND_RESULT: return "SEND_RESULT";
1225 case DESTROY_ACTIVITY: return "DESTROY_ACTIVITY";
1226 case BIND_APPLICATION: return "BIND_APPLICATION";
1227 case EXIT_APPLICATION: return "EXIT_APPLICATION";
1228 case NEW_INTENT: return "NEW_INTENT";
1229 case RECEIVER: return "RECEIVER";
1230 case CREATE_SERVICE: return "CREATE_SERVICE";
1231 case SERVICE_ARGS: return "SERVICE_ARGS";
1232 case STOP_SERVICE: return "STOP_SERVICE";
1233 case CONFIGURATION_CHANGED: return "CONFIGURATION_CHANGED";
1234 case CLEAN_UP_CONTEXT: return "CLEAN_UP_CONTEXT";
1235 case GC_WHEN_IDLE: return "GC_WHEN_IDLE";
1236 case BIND_SERVICE: return "BIND_SERVICE";
1237 case UNBIND_SERVICE: return "UNBIND_SERVICE";
1238 case DUMP_SERVICE: return "DUMP_SERVICE";
1239 case LOW_MEMORY: return "LOW_MEMORY";
1240 case ACTIVITY_CONFIGURATION_CHANGED: return "ACTIVITY_CONFIGURATION_CHANGED";
1241 case RELAUNCH_ACTIVITY: return "RELAUNCH_ACTIVITY";
1242 case PROFILER_CONTROL: return "PROFILER_CONTROL";
1243 case CREATE_BACKUP_AGENT: return "CREATE_BACKUP_AGENT";
1244 case DESTROY_BACKUP_AGENT: return "DESTROY_BACKUP_AGENT";
1245 case SUICIDE: return "SUICIDE";
1246 case REMOVE_PROVIDER: return "REMOVE_PROVIDER";
1247 case ENABLE_JIT: return "ENABLE_JIT";
1248 case DISPATCH_PACKAGE_BROADCAST: return "DISPATCH_PACKAGE_BROADCAST";
1249 case SCHEDULE_CRASH: return "SCHEDULE_CRASH";
1250 case DUMP_HEAP: return "DUMP_HEAP";
1251 case DUMP_ACTIVITY: return "DUMP_ACTIVITY";
1252 case SLEEPING: return "SLEEPING";
1253 case SET_CORE_SETTINGS: return "SET_CORE_SETTINGS";
1254 case UPDATE_PACKAGE_COMPATIBILITY_INFO: return "UPDATE_PACKAGE_COMPATIBILITY_INFO";
1255 case TRIM_MEMORY: return "TRIM_MEMORY";
1256 case DUMP_PROVIDER: return "DUMP_PROVIDER";
1257 case UNSTABLE_PROVIDER_DIED: return "UNSTABLE_PROVIDER_DIED";
1258 case REQUEST_ASSIST_CONTEXT_EXTRAS: return "REQUEST_ASSIST_CONTEXT_EXTRAS";
1259 case TRANSLUCENT_CONVERSION_COMPLETE: return "TRANSLUCENT_CONVERSION_COMPLETE";
1260 case INSTALL_PROVIDER: return "INSTALL_PROVIDER";
1261 case ON_NEW_ACTIVITY_OPTIONS: return "ON_NEW_ACTIVITY_OPTIONS";
1262 case CANCEL_VISIBLE_BEHIND: return "CANCEL_VISIBLE_BEHIND";
1263 case BACKGROUND_VISIBLE_BEHIND_CHANGED: return "BACKGROUND_VISIBLE_BEHIND_CHANGED";
1264 case ENTER_ANIMATION_COMPLETE: return "ENTER_ANIMATION_COMPLETE";
1267 return Integer.toString(code);
1269 public void handleMessage(Message msg) {
1270 if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
1272 case LAUNCH_ACTIVITY: {
1273 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
1274 final ActivityClientRecord r = (ActivityClientRecord) msg.obj;
1276 r.packageInfo = getPackageInfoNoCheck(
1277 r.activityInfo.applicationInfo, r.compatInfo);
1278 handleLaunchActivity(r, null);
1279 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1281 case RELAUNCH_ACTIVITY: {
1282 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityRestart");
1283 ActivityClientRecord r = (ActivityClientRecord)msg.obj;
1284 handleRelaunchActivity(r);
1285 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1287 case PAUSE_ACTIVITY:
1288 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
1289 handlePauseActivity((IBinder)msg.obj, false, (msg.arg1&1) != 0, msg.arg2,
1292 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1294 case PAUSE_ACTIVITY_FINISHING:
1295 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
1296 handlePauseActivity((IBinder)msg.obj, true, (msg.arg1&1) != 0, msg.arg2,
1298 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1300 case STOP_ACTIVITY_SHOW:
1301 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStop");
1302 handleStopActivity((IBinder)msg.obj, true, msg.arg2);
1303 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1305 case STOP_ACTIVITY_HIDE:
1306 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStop");
1307 handleStopActivity((IBinder)msg.obj, false, msg.arg2);
1308 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1311 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityShowWindow");
1312 handleWindowVisibility((IBinder)msg.obj, true);
1313 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1316 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityHideWindow");
1317 handleWindowVisibility((IBinder)msg.obj, false);
1318 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1320 case RESUME_ACTIVITY:
1321 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityResume");
1322 handleResumeActivity((IBinder) msg.obj, true, msg.arg1 != 0, true);
1323 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1326 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityDeliverResult");
1327 handleSendResult((ResultData)msg.obj);
1328 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1330 case DESTROY_ACTIVITY:
1331 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityDestroy");
1332 handleDestroyActivity((IBinder)msg.obj, msg.arg1 != 0,
1334 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1336 case BIND_APPLICATION:
1337 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
1338 AppBindData data = (AppBindData)msg.obj;
1339 handleBindApplication(data);
1340 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1342 case EXIT_APPLICATION:
1343 if (mInitialApplication != null) {
1344 mInitialApplication.onTerminate();
1346 Looper.myLooper().quit();
1349 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityNewIntent");
1350 handleNewIntent((NewIntentData)msg.obj);
1351 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1354 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "broadcastReceiveComp");
1355 handleReceiver((ReceiverData)msg.obj);
1357 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1359 case CREATE_SERVICE:
1360 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceCreate");
1361 handleCreateService((CreateServiceData)msg.obj);
1362 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1365 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceBind");
1366 handleBindService((BindServiceData)msg.obj);
1367 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1369 case UNBIND_SERVICE:
1370 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceUnbind");
1371 handleUnbindService((BindServiceData)msg.obj);
1372 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1375 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceStart");
1376 handleServiceArgs((ServiceArgsData)msg.obj);
1377 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1380 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceStop");
1381 handleStopService((IBinder)msg.obj);
1383 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1385 case CONFIGURATION_CHANGED:
1386 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "configChanged");
1387 mCurDefaultDisplayDpi = ((Configuration)msg.obj).densityDpi;
1388 handleConfigurationChanged((Configuration)msg.obj, null);
1389 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1391 case CLEAN_UP_CONTEXT:
1392 ContextCleanupInfo cci = (ContextCleanupInfo)msg.obj;
1393 cci.context.performFinalCleanup(cci.who, cci.what);
1399 handleDumpService((DumpComponentInfo)msg.obj);
1402 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "lowMemory");
1404 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1406 case ACTIVITY_CONFIGURATION_CHANGED:
1407 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityConfigChanged");
1408 handleActivityConfigurationChanged((IBinder)msg.obj);
1409 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1411 case PROFILER_CONTROL:
1412 handleProfilerControl(msg.arg1 != 0, (ProfilerInfo)msg.obj, msg.arg2);
1414 case CREATE_BACKUP_AGENT:
1415 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "backupCreateAgent");
1416 handleCreateBackupAgent((CreateBackupAgentData)msg.obj);
1417 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1419 case DESTROY_BACKUP_AGENT:
1420 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "backupDestroyAgent");
1421 handleDestroyBackupAgent((CreateBackupAgentData)msg.obj);
1422 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1425 Process.killProcess(Process.myPid());
1427 case REMOVE_PROVIDER:
1428 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "providerRemove");
1429 completeRemoveProvider((ProviderRefCount)msg.obj);
1430 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1435 case DISPATCH_PACKAGE_BROADCAST:
1436 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "broadcastPackage");
1437 handleDispatchPackageBroadcast(msg.arg1, (String[])msg.obj);
1438 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1440 case SCHEDULE_CRASH:
1441 throw new RemoteServiceException((String)msg.obj);
1443 handleDumpHeap(msg.arg1 != 0, (DumpHeapData)msg.obj);
1446 handleDumpActivity((DumpComponentInfo)msg.obj);
1449 handleDumpProvider((DumpComponentInfo)msg.obj);
1452 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "sleeping");
1453 handleSleeping((IBinder)msg.obj, msg.arg1 != 0);
1454 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1456 case SET_CORE_SETTINGS:
1457 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "setCoreSettings");
1458 handleSetCoreSettings((Bundle) msg.obj);
1459 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1461 case UPDATE_PACKAGE_COMPATIBILITY_INFO:
1462 handleUpdatePackageCompatibilityInfo((UpdateCompatibilityData)msg.obj);
1465 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "trimMemory");
1466 handleTrimMemory(msg.arg1);
1467 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1469 case UNSTABLE_PROVIDER_DIED:
1470 handleUnstableProviderDied((IBinder)msg.obj, false);
1472 case REQUEST_ASSIST_CONTEXT_EXTRAS:
1473 handleRequestAssistContextExtras((RequestAssistContextExtras)msg.obj);
1475 case TRANSLUCENT_CONVERSION_COMPLETE:
1476 handleTranslucentConversionComplete((IBinder)msg.obj, msg.arg1 == 1);
1478 case INSTALL_PROVIDER:
1479 handleInstallProvider((ProviderInfo) msg.obj);
1481 case ON_NEW_ACTIVITY_OPTIONS:
1482 Pair<IBinder, ActivityOptions> pair = (Pair<IBinder, ActivityOptions>) msg.obj;
1483 onNewActivityOptions(pair.first, pair.second);
1485 case CANCEL_VISIBLE_BEHIND:
1486 handleCancelVisibleBehind((IBinder) msg.obj);
1488 case BACKGROUND_VISIBLE_BEHIND_CHANGED:
1489 handleOnBackgroundVisibleBehindChanged((IBinder) msg.obj, msg.arg1 > 0);
1491 case ENTER_ANIMATION_COMPLETE:
1492 handleEnterAnimationComplete((IBinder) msg.obj);
1495 if (DEBUG_MESSAGES) Slog.v(TAG, "<<< done: " + codeToString(msg.what));
1498 private void maybeSnapshot() {
1499 if (mBoundApplication != null && SamplingProfilerIntegration.isEnabled()) {
1500 // convert the *private* ActivityThread.PackageInfo to *public* known
1501 // android.content.pm.PackageInfo
1502 String packageName = mBoundApplication.info.mPackageName;
1503 android.content.pm.PackageInfo packageInfo = null;
1505 Context context = getSystemContext();
1506 if(context == null) {
1507 Log.e(TAG, "cannot get a valid context");
1510 PackageManager pm = context.getPackageManager();
1512 Log.e(TAG, "cannot get a valid PackageManager");
1515 packageInfo = pm.getPackageInfo(
1516 packageName, PackageManager.GET_ACTIVITIES);
1517 } catch (NameNotFoundException e) {
1518 Log.e(TAG, "cannot get package info for " + packageName, e);
1520 SamplingProfilerIntegration.writeSnapshot(mBoundApplication.processName, packageInfo);
1525 private class Idler implements MessageQueue.IdleHandler {
1527 public final boolean queueIdle() {
1528 ActivityClientRecord a = mNewActivities;
1529 boolean stopProfiling = false;
1530 if (mBoundApplication != null && mProfiler.profileFd != null
1531 && mProfiler.autoStopProfiler) {
1532 stopProfiling = true;
1535 mNewActivities = null;
1536 IActivityManager am = ActivityManagerNative.getDefault();
1537 ActivityClientRecord prev;
1539 if (localLOGV) Slog.v(
1540 TAG, "Reporting idle of " + a +
1542 (a.activity != null && a.activity.mFinished));
1543 if (a.activity != null && !a.activity.mFinished) {
1545 am.activityIdle(a.token, a.createdConfig, stopProfiling);
1546 a.createdConfig = null;
1547 } catch (RemoteException ex) {
1553 prev.nextIdle = null;
1554 } while (a != null);
1556 if (stopProfiling) {
1557 mProfiler.stopProfiling();
1564 final class GcIdler implements MessageQueue.IdleHandler {
1566 public final boolean queueIdle() {
1572 public static ActivityThread currentActivityThread() {
1573 return sCurrentActivityThread;
1576 public static String currentPackageName() {
1577 ActivityThread am = currentActivityThread();
1578 return (am != null && am.mBoundApplication != null)
1579 ? am.mBoundApplication.appInfo.packageName : null;
1582 public static String currentProcessName() {
1583 ActivityThread am = currentActivityThread();
1584 return (am != null && am.mBoundApplication != null)
1585 ? am.mBoundApplication.processName : null;
1588 public static Application currentApplication() {
1589 ActivityThread am = currentActivityThread();
1590 return am != null ? am.mInitialApplication : null;
1593 public static IPackageManager getPackageManager() {
1594 if (sPackageManager != null) {
1595 //Slog.v("PackageManager", "returning cur default = " + sPackageManager);
1596 return sPackageManager;
1598 IBinder b = ServiceManager.getService("package");
1599 //Slog.v("PackageManager", "default service binder = " + b);
1600 sPackageManager = IPackageManager.Stub.asInterface(b);
1601 //Slog.v("PackageManager", "default service = " + sPackageManager);
1602 return sPackageManager;
1605 private Configuration mMainThreadConfig = new Configuration();
1606 Configuration applyConfigCompatMainThread(int displayDensity, Configuration config,
1607 CompatibilityInfo compat) {
1608 if (config == null) {
1611 if (!compat.supportsScreen()) {
1612 mMainThreadConfig.setTo(config);
1613 config = mMainThreadConfig;
1614 compat.applyToConfiguration(displayDensity, config);
1620 * Creates the top level resources for the given package.
1622 Resources getTopLevelResources(String resDir, String[] splitResDirs, String[] overlayDirs,
1623 String[] libDirs, int displayId, Configuration overrideConfiguration,
1624 LoadedApk pkgInfo) {
1625 return mResourcesManager.getTopLevelResources(resDir, splitResDirs, overlayDirs, libDirs,
1626 displayId, overrideConfiguration, pkgInfo.getCompatibilityInfo(), null);
1629 final Handler getHandler() {
1633 public final LoadedApk getPackageInfo(String packageName, CompatibilityInfo compatInfo,
1635 return getPackageInfo(packageName, compatInfo, flags, UserHandle.myUserId());
1638 public final LoadedApk getPackageInfo(String packageName, CompatibilityInfo compatInfo,
1639 int flags, int userId) {
1640 synchronized (mResourcesManager) {
1641 WeakReference<LoadedApk> ref;
1642 if ((flags&Context.CONTEXT_INCLUDE_CODE) != 0) {
1643 ref = mPackages.get(packageName);
1645 ref = mResourcePackages.get(packageName);
1647 LoadedApk packageInfo = ref != null ? ref.get() : null;
1648 //Slog.i(TAG, "getPackageInfo " + packageName + ": " + packageInfo);
1649 //if (packageInfo != null) Slog.i(TAG, "isUptoDate " + packageInfo.mResDir
1650 // + ": " + packageInfo.mResources.getAssets().isUpToDate());
1651 if (packageInfo != null && (packageInfo.mResources == null
1652 || packageInfo.mResources.getAssets().isUpToDate())) {
1653 if (packageInfo.isSecurityViolation()
1654 && (flags&Context.CONTEXT_IGNORE_SECURITY) == 0) {
1655 throw new SecurityException(
1656 "Requesting code from " + packageName
1657 + " to be run in process "
1658 + mBoundApplication.processName
1659 + "/" + mBoundApplication.appInfo.uid);
1665 ApplicationInfo ai = null;
1667 ai = getPackageManager().getApplicationInfo(packageName,
1668 PackageManager.GET_SHARED_LIBRARY_FILES, userId);
1669 } catch (RemoteException e) {
1674 return getPackageInfo(ai, compatInfo, flags);
1680 public final LoadedApk getPackageInfo(ApplicationInfo ai, CompatibilityInfo compatInfo,
1682 boolean includeCode = (flags&Context.CONTEXT_INCLUDE_CODE) != 0;
1683 boolean securityViolation = includeCode && ai.uid != 0
1684 && ai.uid != Process.SYSTEM_UID && (mBoundApplication != null
1685 ? !UserHandle.isSameApp(ai.uid, mBoundApplication.appInfo.uid)
1687 boolean registerPackage = includeCode && (flags&Context.CONTEXT_REGISTER_PACKAGE) != 0;
1688 if ((flags&(Context.CONTEXT_INCLUDE_CODE
1689 |Context.CONTEXT_IGNORE_SECURITY))
1690 == Context.CONTEXT_INCLUDE_CODE) {
1691 if (securityViolation) {
1692 String msg = "Requesting code from " + ai.packageName
1693 + " (with uid " + ai.uid + ")";
1694 if (mBoundApplication != null) {
1695 msg = msg + " to be run in process "
1696 + mBoundApplication.processName + " (with uid "
1697 + mBoundApplication.appInfo.uid + ")";
1699 throw new SecurityException(msg);
1702 return getPackageInfo(ai, compatInfo, null, securityViolation, includeCode,
1706 public final LoadedApk getPackageInfoNoCheck(ApplicationInfo ai,
1707 CompatibilityInfo compatInfo) {
1708 return getPackageInfo(ai, compatInfo, null, false, true, false);
1711 public final LoadedApk peekPackageInfo(String packageName, boolean includeCode) {
1712 synchronized (mResourcesManager) {
1713 WeakReference<LoadedApk> ref;
1715 ref = mPackages.get(packageName);
1717 ref = mResourcePackages.get(packageName);
1719 return ref != null ? ref.get() : null;
1723 private LoadedApk getPackageInfo(ApplicationInfo aInfo, CompatibilityInfo compatInfo,
1724 ClassLoader baseLoader, boolean securityViolation, boolean includeCode,
1725 boolean registerPackage) {
1726 synchronized (mResourcesManager) {
1727 WeakReference<LoadedApk> ref;
1729 ref = mPackages.get(aInfo.packageName);
1731 ref = mResourcePackages.get(aInfo.packageName);
1733 LoadedApk packageInfo = ref != null ? ref.get() : null;
1734 if (packageInfo == null || (packageInfo.mResources != null
1735 && !packageInfo.mResources.getAssets().isUpToDate())) {
1736 if (localLOGV) Slog.v(TAG, (includeCode ? "Loading code package "
1737 : "Loading resource-only package ") + aInfo.packageName
1738 + " (in " + (mBoundApplication != null
1739 ? mBoundApplication.processName : null)
1742 new LoadedApk(this, aInfo, compatInfo, baseLoader,
1743 securityViolation, includeCode &&
1744 (aInfo.flags&ApplicationInfo.FLAG_HAS_CODE) != 0, registerPackage);
1746 mPackages.put(aInfo.packageName,
1747 new WeakReference<LoadedApk>(packageInfo));
1749 mResourcePackages.put(aInfo.packageName,
1750 new WeakReference<LoadedApk>(packageInfo));
1758 mResourcesManager = ResourcesManager.getInstance();
1761 public ApplicationThread getApplicationThread()
1766 public Instrumentation getInstrumentation()
1768 return mInstrumentation;
1771 public boolean isProfiling() {
1772 return mProfiler != null && mProfiler.profileFile != null
1773 && mProfiler.profileFd == null;
1776 public String getProfileFilePath() {
1777 return mProfiler.profileFile;
1780 public Looper getLooper() {
1784 public Application getApplication() {
1785 return mInitialApplication;
1788 public String getProcessName() {
1789 return mBoundApplication.processName;
1792 public ContextImpl getSystemContext() {
1793 synchronized (this) {
1794 if (mSystemContext == null) {
1795 mSystemContext = ContextImpl.createSystemContext(this);
1797 return mSystemContext;
1801 public void installSystemApplicationInfo(ApplicationInfo info, ClassLoader classLoader) {
1802 synchronized (this) {
1803 getSystemContext().installSystemApplicationInfo(info, classLoader);
1805 // The code package for "android" in the system server needs
1806 // to be the system context's package.
1807 mPackages.put("android", new WeakReference<LoadedApk>(getSystemContext().mPackageInfo));
1809 // give ourselves a default profiler
1810 mProfiler = new Profiler();
1814 void ensureJitEnabled() {
1817 dalvik.system.VMRuntime.getRuntime().startJitCompilation();
1821 void scheduleGcIdler() {
1822 if (!mGcIdlerScheduled) {
1823 mGcIdlerScheduled = true;
1824 Looper.myQueue().addIdleHandler(mGcIdler);
1826 mH.removeMessages(H.GC_WHEN_IDLE);
1829 void unscheduleGcIdler() {
1830 if (mGcIdlerScheduled) {
1831 mGcIdlerScheduled = false;
1832 Looper.myQueue().removeIdleHandler(mGcIdler);
1834 mH.removeMessages(H.GC_WHEN_IDLE);
1837 void doGcIfNeeded() {
1838 mGcIdlerScheduled = false;
1839 final long now = SystemClock.uptimeMillis();
1840 //Slog.i(TAG, "**** WE MIGHT WANT TO GC: then=" + Binder.getLastGcTime()
1841 // + "m now=" + now);
1842 if ((BinderInternal.getLastGcTime()+MIN_TIME_BETWEEN_GCS) < now) {
1843 //Slog.i(TAG, "**** WE DO, WE DO WANT TO GC!");
1844 BinderInternal.forceGc("bg");
1848 private static final String HEAP_FULL_COLUMN
1849 = "%13s %8s %8s %8s %8s %8s %8s %8s %8s %8s %8s";
1850 private static final String HEAP_COLUMN
1851 = "%13s %8s %8s %8s %8s %8s %8s %8s";
1853 // Formatting for checkin service - update version if row format changes
1854 private static final int ACTIVITY_THREAD_CHECKIN_VERSION = 3;
1856 static void printRow(PrintWriter pw, String format, Object...objs) {
1857 pw.println(String.format(format, objs));
1860 public static void dumpMemInfoTable(PrintWriter pw, Debug.MemoryInfo memInfo, boolean checkin,
1861 boolean dumpFullInfo, boolean dumpDalvik, int pid, String processName,
1862 long nativeMax, long nativeAllocated, long nativeFree,
1863 long dalvikMax, long dalvikAllocated, long dalvikFree) {
1865 // For checkin, we print one long comma-separated list of values
1867 // NOTE: if you change anything significant below, also consider changing
1868 // ACTIVITY_THREAD_CHECKIN_VERSION.
1871 pw.print(ACTIVITY_THREAD_CHECKIN_VERSION); pw.print(',');
1872 pw.print(pid); pw.print(',');
1873 pw.print(processName); pw.print(',');
1876 pw.print(nativeMax); pw.print(',');
1877 pw.print(dalvikMax); pw.print(',');
1879 pw.print(nativeMax + dalvikMax); pw.print(',');
1881 // Heap info - allocated
1882 pw.print(nativeAllocated); pw.print(',');
1883 pw.print(dalvikAllocated); pw.print(',');
1885 pw.print(nativeAllocated + dalvikAllocated); pw.print(',');
1888 pw.print(nativeFree); pw.print(',');
1889 pw.print(dalvikFree); pw.print(',');
1891 pw.print(nativeFree + dalvikFree); pw.print(',');
1893 // Heap info - proportional set size
1894 pw.print(memInfo.nativePss); pw.print(',');
1895 pw.print(memInfo.dalvikPss); pw.print(',');
1896 pw.print(memInfo.otherPss); pw.print(',');
1897 pw.print(memInfo.getTotalPss()); pw.print(',');
1899 // Heap info - swappable set size
1900 pw.print(memInfo.nativeSwappablePss); pw.print(',');
1901 pw.print(memInfo.dalvikSwappablePss); pw.print(',');
1902 pw.print(memInfo.otherSwappablePss); pw.print(',');
1903 pw.print(memInfo.getTotalSwappablePss()); pw.print(',');
1905 // Heap info - shared dirty
1906 pw.print(memInfo.nativeSharedDirty); pw.print(',');
1907 pw.print(memInfo.dalvikSharedDirty); pw.print(',');
1908 pw.print(memInfo.otherSharedDirty); pw.print(',');
1909 pw.print(memInfo.getTotalSharedDirty()); pw.print(',');
1911 // Heap info - shared clean
1912 pw.print(memInfo.nativeSharedClean); pw.print(',');
1913 pw.print(memInfo.dalvikSharedClean); pw.print(',');
1914 pw.print(memInfo.otherSharedClean); pw.print(',');
1915 pw.print(memInfo.getTotalSharedClean()); pw.print(',');
1917 // Heap info - private Dirty
1918 pw.print(memInfo.nativePrivateDirty); pw.print(',');
1919 pw.print(memInfo.dalvikPrivateDirty); pw.print(',');
1920 pw.print(memInfo.otherPrivateDirty); pw.print(',');
1921 pw.print(memInfo.getTotalPrivateDirty()); pw.print(',');
1923 // Heap info - private Clean
1924 pw.print(memInfo.nativePrivateClean); pw.print(',');
1925 pw.print(memInfo.dalvikPrivateClean); pw.print(',');
1926 pw.print(memInfo.otherPrivateClean); pw.print(',');
1927 pw.print(memInfo.getTotalPrivateClean()); pw.print(',');
1929 // Heap info - other areas
1930 for (int i=0; i<Debug.MemoryInfo.NUM_OTHER_STATS; i++) {
1931 pw.print(Debug.MemoryInfo.getOtherLabel(i)); pw.print(',');
1932 pw.print(memInfo.getOtherPss(i)); pw.print(',');
1933 pw.print(memInfo.getOtherSwappablePss(i)); pw.print(',');
1934 pw.print(memInfo.getOtherSharedDirty(i)); pw.print(',');
1935 pw.print(memInfo.getOtherSharedClean(i)); pw.print(',');
1936 pw.print(memInfo.getOtherPrivateDirty(i)); pw.print(',');
1937 pw.print(memInfo.getOtherPrivateClean(i)); pw.print(',');
1942 // otherwise, show human-readable format
1944 printRow(pw, HEAP_FULL_COLUMN, "", "Pss", "Pss", "Shared", "Private",
1945 "Shared", "Private", "Swapped", "Heap", "Heap", "Heap");
1946 printRow(pw, HEAP_FULL_COLUMN, "", "Total", "Clean", "Dirty", "",
1947 "Clean", "Clean", "Dirty", "Size", "Alloc", "Free");
1948 printRow(pw, HEAP_FULL_COLUMN, "", "------", "------", "------", "------",
1949 "------", "------", "------", "------", "------", "------");
1950 printRow(pw, HEAP_FULL_COLUMN, "Native Heap", memInfo.nativePss,
1951 memInfo.nativeSwappablePss, memInfo.nativeSharedDirty,
1952 memInfo.nativePrivateDirty, memInfo.nativeSharedClean,
1953 memInfo.nativePrivateClean, memInfo.nativeSwappedOut,
1954 nativeMax, nativeAllocated, nativeFree);
1955 printRow(pw, HEAP_FULL_COLUMN, "Dalvik Heap", memInfo.dalvikPss,
1956 memInfo.dalvikSwappablePss, memInfo.dalvikSharedDirty,
1957 memInfo.dalvikPrivateDirty, memInfo.dalvikSharedClean,
1958 memInfo.dalvikPrivateClean, memInfo.dalvikSwappedOut,
1959 dalvikMax, dalvikAllocated, dalvikFree);
1961 printRow(pw, HEAP_COLUMN, "", "Pss", "Private",
1962 "Private", "Swapped", "Heap", "Heap", "Heap");
1963 printRow(pw, HEAP_COLUMN, "", "Total", "Dirty",
1964 "Clean", "Dirty", "Size", "Alloc", "Free");
1965 printRow(pw, HEAP_COLUMN, "", "------", "------", "------",
1966 "------", "------", "------", "------", "------");
1967 printRow(pw, HEAP_COLUMN, "Native Heap", memInfo.nativePss,
1968 memInfo.nativePrivateDirty,
1969 memInfo.nativePrivateClean, memInfo.nativeSwappedOut,
1970 nativeMax, nativeAllocated, nativeFree);
1971 printRow(pw, HEAP_COLUMN, "Dalvik Heap", memInfo.dalvikPss,
1972 memInfo.dalvikPrivateDirty,
1973 memInfo.dalvikPrivateClean, memInfo.dalvikSwappedOut,
1974 dalvikMax, dalvikAllocated, dalvikFree);
1977 int otherPss = memInfo.otherPss;
1978 int otherSwappablePss = memInfo.otherSwappablePss;
1979 int otherSharedDirty = memInfo.otherSharedDirty;
1980 int otherPrivateDirty = memInfo.otherPrivateDirty;
1981 int otherSharedClean = memInfo.otherSharedClean;
1982 int otherPrivateClean = memInfo.otherPrivateClean;
1983 int otherSwappedOut = memInfo.otherSwappedOut;
1985 for (int i=0; i<Debug.MemoryInfo.NUM_OTHER_STATS; i++) {
1986 final int myPss = memInfo.getOtherPss(i);
1987 final int mySwappablePss = memInfo.getOtherSwappablePss(i);
1988 final int mySharedDirty = memInfo.getOtherSharedDirty(i);
1989 final int myPrivateDirty = memInfo.getOtherPrivateDirty(i);
1990 final int mySharedClean = memInfo.getOtherSharedClean(i);
1991 final int myPrivateClean = memInfo.getOtherPrivateClean(i);
1992 final int mySwappedOut = memInfo.getOtherSwappedOut(i);
1993 if (myPss != 0 || mySharedDirty != 0 || myPrivateDirty != 0
1994 || mySharedClean != 0 || myPrivateClean != 0 || mySwappedOut != 0) {
1996 printRow(pw, HEAP_FULL_COLUMN, Debug.MemoryInfo.getOtherLabel(i),
1997 myPss, mySwappablePss, mySharedDirty, myPrivateDirty,
1998 mySharedClean, myPrivateClean, mySwappedOut, "", "", "");
2000 printRow(pw, HEAP_COLUMN, Debug.MemoryInfo.getOtherLabel(i),
2001 myPss, myPrivateDirty,
2002 myPrivateClean, mySwappedOut, "", "", "");
2005 otherSwappablePss -= mySwappablePss;
2006 otherSharedDirty -= mySharedDirty;
2007 otherPrivateDirty -= myPrivateDirty;
2008 otherSharedClean -= mySharedClean;
2009 otherPrivateClean -= myPrivateClean;
2010 otherSwappedOut -= mySwappedOut;
2015 printRow(pw, HEAP_FULL_COLUMN, "Unknown", otherPss, otherSwappablePss,
2016 otherSharedDirty, otherPrivateDirty, otherSharedClean, otherPrivateClean,
2017 otherSwappedOut, "", "", "");
2018 printRow(pw, HEAP_FULL_COLUMN, "TOTAL", memInfo.getTotalPss(),
2019 memInfo.getTotalSwappablePss(),
2020 memInfo.getTotalSharedDirty(), memInfo.getTotalPrivateDirty(),
2021 memInfo.getTotalSharedClean(), memInfo.getTotalPrivateClean(),
2022 memInfo.getTotalSwappedOut(), nativeMax+dalvikMax,
2023 nativeAllocated+dalvikAllocated, nativeFree+dalvikFree);
2025 printRow(pw, HEAP_COLUMN, "Unknown", otherPss,
2026 otherPrivateDirty, otherPrivateClean, otherSwappedOut,
2028 printRow(pw, HEAP_COLUMN, "TOTAL", memInfo.getTotalPss(),
2029 memInfo.getTotalPrivateDirty(),
2030 memInfo.getTotalPrivateClean(),
2031 memInfo.getTotalSwappedOut(),
2032 nativeMax+dalvikMax,
2033 nativeAllocated+dalvikAllocated, nativeFree+dalvikFree);
2038 pw.println(" Dalvik Details");
2040 for (int i=Debug.MemoryInfo.NUM_OTHER_STATS;
2041 i<Debug.MemoryInfo.NUM_OTHER_STATS + Debug.MemoryInfo.NUM_DVK_STATS; i++) {
2042 final int myPss = memInfo.getOtherPss(i);
2043 final int mySwappablePss = memInfo.getOtherSwappablePss(i);
2044 final int mySharedDirty = memInfo.getOtherSharedDirty(i);
2045 final int myPrivateDirty = memInfo.getOtherPrivateDirty(i);
2046 final int mySharedClean = memInfo.getOtherSharedClean(i);
2047 final int myPrivateClean = memInfo.getOtherPrivateClean(i);
2048 final int mySwappedOut = memInfo.getOtherSwappedOut(i);
2049 if (myPss != 0 || mySharedDirty != 0 || myPrivateDirty != 0
2050 || mySharedClean != 0 || myPrivateClean != 0) {
2052 printRow(pw, HEAP_FULL_COLUMN, Debug.MemoryInfo.getOtherLabel(i),
2053 myPss, mySwappablePss, mySharedDirty, myPrivateDirty,
2054 mySharedClean, myPrivateClean, mySwappedOut, "", "", "");
2056 printRow(pw, HEAP_COLUMN, Debug.MemoryInfo.getOtherLabel(i),
2057 myPss, myPrivateDirty,
2058 myPrivateClean, mySwappedOut, "", "", "");
2065 public void registerOnActivityPausedListener(Activity activity,
2066 OnActivityPausedListener listener) {
2067 synchronized (mOnPauseListeners) {
2068 ArrayList<OnActivityPausedListener> list = mOnPauseListeners.get(activity);
2070 list = new ArrayList<OnActivityPausedListener>();
2071 mOnPauseListeners.put(activity, list);
2077 public void unregisterOnActivityPausedListener(Activity activity,
2078 OnActivityPausedListener listener) {
2079 synchronized (mOnPauseListeners) {
2080 ArrayList<OnActivityPausedListener> list = mOnPauseListeners.get(activity);
2082 list.remove(listener);
2087 public final ActivityInfo resolveActivityInfo(Intent intent) {
2088 ActivityInfo aInfo = intent.resolveActivityInfo(
2089 mInitialApplication.getPackageManager(), PackageManager.GET_SHARED_LIBRARY_FILES);
2090 if (aInfo == null) {
2091 // Throw an exception.
2092 Instrumentation.checkStartActivityResult(
2093 ActivityManager.START_CLASS_NOT_FOUND, intent);
2098 public final Activity startActivityNow(Activity parent, String id,
2099 Intent intent, ActivityInfo activityInfo, IBinder token, Bundle state,
2100 Activity.NonConfigurationInstances lastNonConfigurationInstances) {
2101 ActivityClientRecord r = new ActivityClientRecord();
2108 r.activityInfo = activityInfo;
2109 r.lastNonConfigurationInstances = lastNonConfigurationInstances;
2111 ComponentName compname = intent.getComponent();
2113 if (compname != null) {
2114 name = compname.toShortString();
2116 name = "(Intent " + intent + ").getComponent() returned null";
2118 Slog.v(TAG, "Performing launch: action=" + intent.getAction()
2120 + ", token=" + token);
2122 return performLaunchActivity(r, null);
2125 public final Activity getActivity(IBinder token) {
2126 return mActivities.get(token).activity;
2129 public final void sendActivityResult(
2130 IBinder token, String id, int requestCode,
2131 int resultCode, Intent data) {
2132 if (DEBUG_RESULTS) Slog.v(TAG, "sendActivityResult: id=" + id
2133 + " req=" + requestCode + " res=" + resultCode + " data=" + data);
2134 ArrayList<ResultInfo> list = new ArrayList<ResultInfo>();
2135 list.add(new ResultInfo(id, requestCode, resultCode, data));
2136 mAppThread.scheduleSendResult(token, list);
2139 private void sendMessage(int what, Object obj) {
2140 sendMessage(what, obj, 0, 0, false);
2143 private void sendMessage(int what, Object obj, int arg1) {
2144 sendMessage(what, obj, arg1, 0, false);
2147 private void sendMessage(int what, Object obj, int arg1, int arg2) {
2148 sendMessage(what, obj, arg1, arg2, false);
2151 private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
2152 if (DEBUG_MESSAGES) Slog.v(
2153 TAG, "SCHEDULE " + what + " " + mH.codeToString(what)
2154 + ": " + arg1 + " / " + obj);
2155 Message msg = Message.obtain();
2161 msg.setAsynchronous(true);
2163 mH.sendMessage(msg);
2166 final void scheduleContextCleanup(ContextImpl context, String who,
2168 ContextCleanupInfo cci = new ContextCleanupInfo();
2169 cci.context = context;
2172 sendMessage(H.CLEAN_UP_CONTEXT, cci);
2175 private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
2176 // System.out.println("##### [" + System.currentTimeMillis() + "] ActivityThread.performLaunchActivity(" + r + ")");
2178 ActivityInfo aInfo = r.activityInfo;
2179 if (r.packageInfo == null) {
2180 r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
2181 Context.CONTEXT_INCLUDE_CODE);
2184 ComponentName component = r.intent.getComponent();
2185 if (component == null) {
2186 component = r.intent.resolveActivity(
2187 mInitialApplication.getPackageManager());
2188 r.intent.setComponent(component);
2191 if (r.activityInfo.targetActivity != null) {
2192 component = new ComponentName(r.activityInfo.packageName,
2193 r.activityInfo.targetActivity);
2196 Activity activity = null;
2198 java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
2199 activity = mInstrumentation.newActivity(
2200 cl, component.getClassName(), r.intent);
2201 StrictMode.incrementExpectedActivityCount(activity.getClass());
2202 r.intent.setExtrasClassLoader(cl);
2203 r.intent.prepareToEnterProcess();
2204 if (r.state != null) {
2205 r.state.setClassLoader(cl);
2207 } catch (Exception e) {
2208 if (!mInstrumentation.onException(activity, e)) {
2209 throw new RuntimeException(
2210 "Unable to instantiate activity " + component
2211 + ": " + e.toString(), e);
2216 Application app = r.packageInfo.makeApplication(false, mInstrumentation);
2218 if (localLOGV) Slog.v(TAG, "Performing launch of " + r);
2219 if (localLOGV) Slog.v(
2220 TAG, r + ": app=" + app
2221 + ", appName=" + app.getPackageName()
2222 + ", pkg=" + r.packageInfo.getPackageName()
2223 + ", comp=" + r.intent.getComponent().toShortString()
2224 + ", dir=" + r.packageInfo.getAppDir());
2226 if (activity != null) {
2227 Context appContext = createBaseContextForActivity(r, activity);
2228 CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
2229 Configuration config = new Configuration(mCompatConfiguration);
2230 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "
2231 + r.activityInfo.name + " with config " + config);
2232 activity.attach(appContext, this, getInstrumentation(), r.token,
2233 r.ident, app, r.intent, r.activityInfo, title, r.parent,
2234 r.embeddedID, r.lastNonConfigurationInstances, config,
2237 if (customIntent != null) {
2238 activity.mIntent = customIntent;
2240 r.lastNonConfigurationInstances = null;
2241 activity.mStartedActivity = false;
2242 int theme = r.activityInfo.getThemeResource();
2244 activity.setTheme(theme);
2247 activity.mCalled = false;
2248 if (r.isPersistable()) {
2249 mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
2251 mInstrumentation.callActivityOnCreate(activity, r.state);
2253 if (!activity.mCalled) {
2254 throw new SuperNotCalledException(
2255 "Activity " + r.intent.getComponent().toShortString() +
2256 " did not call through to super.onCreate()");
2258 r.activity = activity;
2260 if (!r.activity.mFinished) {
2261 activity.performStart();
2264 if (!r.activity.mFinished) {
2265 if (r.isPersistable()) {
2266 if (r.state != null || r.persistentState != null) {
2267 mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state,
2270 } else if (r.state != null) {
2271 mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
2274 if (!r.activity.mFinished) {
2275 activity.mCalled = false;
2276 if (r.isPersistable()) {
2277 mInstrumentation.callActivityOnPostCreate(activity, r.state,
2280 mInstrumentation.callActivityOnPostCreate(activity, r.state);
2282 if (!activity.mCalled) {
2283 throw new SuperNotCalledException(
2284 "Activity " + r.intent.getComponent().toShortString() +
2285 " did not call through to super.onPostCreate()");
2291 mActivities.put(r.token, r);
2293 } catch (SuperNotCalledException e) {
2296 } catch (Exception e) {
2297 if (!mInstrumentation.onException(activity, e)) {
2298 throw new RuntimeException(
2299 "Unable to start activity " + component
2300 + ": " + e.toString(), e);
2307 private Context createBaseContextForActivity(ActivityClientRecord r,
2308 final Activity activity) {
2309 ContextImpl appContext = ContextImpl.createActivityContext(this, r.packageInfo, r.token);
2310 appContext.setOuterContext(activity);
2311 Context baseContext = appContext;
2313 final DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance();
2315 IActivityContainer container =
2316 ActivityManagerNative.getDefault().getEnclosingActivityContainer(r.token);
2317 final int displayId =
2318 container == null ? Display.DEFAULT_DISPLAY : container.getDisplayId();
2319 if (displayId > Display.DEFAULT_DISPLAY) {
2320 Display display = dm.getRealDisplay(displayId, r.token);
2321 baseContext = appContext.createDisplayContext(display);
2323 } catch (RemoteException e) {
2326 // For debugging purposes, if the activity's package name contains the value of
2327 // the "debug.use-second-display" system property as a substring, then show
2328 // its content on a secondary display if there is one.
2329 String pkgName = SystemProperties.get("debug.second-display.pkg");
2330 if (pkgName != null && !pkgName.isEmpty()
2331 && r.packageInfo.mPackageName.contains(pkgName)) {
2332 for (int displayId : dm.getDisplayIds()) {
2333 if (displayId != Display.DEFAULT_DISPLAY) {
2334 Display display = dm.getRealDisplay(displayId, r.token);
2335 baseContext = appContext.createDisplayContext(display);
2343 private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
2344 // If we are getting ready to gc after going to the background, well
2345 // we are back active so skip it.
2346 unscheduleGcIdler();
2347 mSomeActivitiesChanged = true;
2349 if (r.profilerInfo != null) {
2350 mProfiler.setProfiler(r.profilerInfo);
2351 mProfiler.startProfiling();
2354 // Make sure we are running with the most recent config.
2355 handleConfigurationChanged(null, null);
2357 if (localLOGV) Slog.v(
2358 TAG, "Handling launch of " + r);
2360 Activity a = performLaunchActivity(r, customIntent);
2363 r.createdConfig = new Configuration(mConfiguration);
2364 Bundle oldState = r.state;
2365 handleResumeActivity(r.token, false, r.isForward,
2366 !r.activity.mFinished && !r.startsNotResumed);
2368 if (!r.activity.mFinished && r.startsNotResumed) {
2369 // The activity manager actually wants this one to start out
2370 // paused, because it needs to be visible but isn't in the
2371 // foreground. We accomplish this by going through the
2372 // normal startup (because activities expect to go through
2373 // onResume() the first time they run, before their window
2374 // is displayed), and then pausing it. However, in this case
2375 // we do -not- need to do the full pause cycle (of freezing
2376 // and such) because the activity manager assumes it can just
2377 // retain the current state it has.
2379 r.activity.mCalled = false;
2380 mInstrumentation.callActivityOnPause(r.activity);
2381 // We need to keep around the original state, in case
2382 // we need to be created again. But we only do this
2383 // for pre-Honeycomb apps, which always save their state
2384 // when pausing, so we can not have them save their state
2385 // when restarting from a paused state. For HC and later,
2386 // we want to (and can) let the state be saved as the normal
2387 // part of stopping the activity.
2388 if (r.isPreHoneycomb()) {
2391 if (!r.activity.mCalled) {
2392 throw new SuperNotCalledException(
2393 "Activity " + r.intent.getComponent().toShortString() +
2394 " did not call through to super.onPause()");
2397 } catch (SuperNotCalledException e) {
2400 } catch (Exception e) {
2401 if (!mInstrumentation.onException(r.activity, e)) {
2402 throw new RuntimeException(
2403 "Unable to pause activity "
2404 + r.intent.getComponent().toShortString()
2405 + ": " + e.toString(), e);
2411 // If there was an error, for any reason, tell the activity
2412 // manager to stop us.
2414 ActivityManagerNative.getDefault()
2415 .finishActivity(r.token, Activity.RESULT_CANCELED, null, false);
2416 } catch (RemoteException ex) {
2422 private void deliverNewIntents(ActivityClientRecord r,
2423 List<Intent> intents) {
2424 final int N = intents.size();
2425 for (int i=0; i<N; i++) {
2426 Intent intent = intents.get(i);
2427 intent.setExtrasClassLoader(r.activity.getClassLoader());
2428 intent.prepareToEnterProcess();
2429 r.activity.mFragments.noteStateNotSaved();
2430 mInstrumentation.callActivityOnNewIntent(r.activity, intent);
2434 public final void performNewIntents(IBinder token,
2435 List<Intent> intents) {
2436 ActivityClientRecord r = mActivities.get(token);
2438 final boolean resumed = !r.paused;
2440 r.activity.mTemporaryPause = true;
2441 mInstrumentation.callActivityOnPause(r.activity);
2443 deliverNewIntents(r, intents);
2445 r.activity.performResume();
2446 r.activity.mTemporaryPause = false;
2451 private void handleNewIntent(NewIntentData data) {
2452 performNewIntents(data.token, data.intents);
2455 public void handleRequestAssistContextExtras(RequestAssistContextExtras cmd) {
2456 Bundle data = new Bundle();
2457 ActivityClientRecord r = mActivities.get(cmd.activityToken);
2459 r.activity.getApplication().dispatchOnProvideAssistData(r.activity, data);
2460 r.activity.onProvideAssistData(data);
2462 if (data.isEmpty()) {
2465 IActivityManager mgr = ActivityManagerNative.getDefault();
2467 mgr.reportAssistContextExtras(cmd.requestToken, data);
2468 } catch (RemoteException e) {
2472 public void handleTranslucentConversionComplete(IBinder token, boolean drawComplete) {
2473 ActivityClientRecord r = mActivities.get(token);
2475 r.activity.onTranslucentConversionComplete(drawComplete);
2479 public void onNewActivityOptions(IBinder token, ActivityOptions options) {
2480 ActivityClientRecord r = mActivities.get(token);
2482 r.activity.onNewActivityOptions(options);
2486 public void handleCancelVisibleBehind(IBinder token) {
2487 ActivityClientRecord r = mActivities.get(token);
2489 mSomeActivitiesChanged = true;
2490 final Activity activity = r.activity;
2491 if (activity.mVisibleBehind) {
2492 activity.mCalled = false;
2493 activity.onVisibleBehindCanceled();
2494 // Tick, tick, tick. The activity has 500 msec to return or it will be destroyed.
2495 if (!activity.mCalled) {
2496 throw new SuperNotCalledException("Activity " + activity.getLocalClassName() +
2497 " did not call through to super.onVisibleBehindCanceled()");
2499 activity.mVisibleBehind = false;
2503 ActivityManagerNative.getDefault().backgroundResourcesReleased(token);
2504 } catch (RemoteException e) {
2508 public void handleOnBackgroundVisibleBehindChanged(IBinder token, boolean visible) {
2509 ActivityClientRecord r = mActivities.get(token);
2511 r.activity.onBackgroundVisibleBehindChanged(visible);
2515 public void handleInstallProvider(ProviderInfo info) {
2516 installContentProviders(mInitialApplication, Lists.newArrayList(info));
2519 private void handleEnterAnimationComplete(IBinder token) {
2520 ActivityClientRecord r = mActivities.get(token);
2522 r.activity.dispatchEnterAnimationComplete();
2526 private static final ThreadLocal<Intent> sCurrentBroadcastIntent = new ThreadLocal<Intent>();
2529 * Return the Intent that's currently being handled by a
2530 * BroadcastReceiver on this thread, or null if none.
2533 public static Intent getIntentBeingBroadcast() {
2534 return sCurrentBroadcastIntent.get();
2537 private void handleReceiver(ReceiverData data) {
2538 // If we are getting ready to gc after going to the background, well
2539 // we are back active so skip it.
2540 unscheduleGcIdler();
2542 String component = data.intent.getComponent().getClassName();
2544 LoadedApk packageInfo = getPackageInfoNoCheck(
2545 data.info.applicationInfo, data.compatInfo);
2547 IActivityManager mgr = ActivityManagerNative.getDefault();
2549 BroadcastReceiver receiver;
2551 java.lang.ClassLoader cl = packageInfo.getClassLoader();
2552 data.intent.setExtrasClassLoader(cl);
2553 data.intent.prepareToEnterProcess();
2554 data.setExtrasClassLoader(cl);
2555 receiver = (BroadcastReceiver)cl.loadClass(component).newInstance();
2556 } catch (Exception e) {
2557 if (DEBUG_BROADCAST) Slog.i(TAG,
2558 "Finishing failed broadcast to " + data.intent.getComponent());
2559 data.sendFinished(mgr);
2560 throw new RuntimeException(
2561 "Unable to instantiate receiver " + component
2562 + ": " + e.toString(), e);
2566 Application app = packageInfo.makeApplication(false, mInstrumentation);
2568 if (localLOGV) Slog.v(
2569 TAG, "Performing receive of " + data.intent
2571 + ", appName=" + app.getPackageName()
2572 + ", pkg=" + packageInfo.getPackageName()
2573 + ", comp=" + data.intent.getComponent().toShortString()
2574 + ", dir=" + packageInfo.getAppDir());
2576 ContextImpl context = (ContextImpl)app.getBaseContext();
2577 sCurrentBroadcastIntent.set(data.intent);
2578 receiver.setPendingResult(data);
2579 receiver.onReceive(context.getReceiverRestrictedContext(),
2581 } catch (Exception e) {
2582 if (DEBUG_BROADCAST) Slog.i(TAG,
2583 "Finishing failed broadcast to " + data.intent.getComponent());
2584 data.sendFinished(mgr);
2585 if (!mInstrumentation.onException(receiver, e)) {
2586 throw new RuntimeException(
2587 "Unable to start receiver " + component
2588 + ": " + e.toString(), e);
2591 sCurrentBroadcastIntent.set(null);
2594 if (receiver.getPendingResult() != null) {
2599 // Instantiate a BackupAgent and tell it that it's alive
2600 private void handleCreateBackupAgent(CreateBackupAgentData data) {
2601 if (DEBUG_BACKUP) Slog.v(TAG, "handleCreateBackupAgent: " + data);
2603 // Sanity check the requested target package's uid against ours
2605 PackageInfo requestedPackage = getPackageManager().getPackageInfo(
2606 data.appInfo.packageName, 0, UserHandle.myUserId());
2607 if (requestedPackage.applicationInfo.uid != Process.myUid()) {
2608 Slog.w(TAG, "Asked to instantiate non-matching package "
2609 + data.appInfo.packageName);
2612 } catch (RemoteException e) {
2613 Slog.e(TAG, "Can't reach package manager", e);
2617 // no longer idle; we have backup work to do
2618 unscheduleGcIdler();
2620 // instantiate the BackupAgent class named in the manifest
2621 LoadedApk packageInfo = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
2622 String packageName = packageInfo.mPackageName;
2623 if (packageName == null) {
2624 Slog.d(TAG, "Asked to create backup agent for nonexistent package");
2628 String classname = data.appInfo.backupAgentName;
2629 // full backup operation but no app-supplied agent? use the default implementation
2630 if (classname == null && (data.backupMode == IApplicationThread.BACKUP_MODE_FULL
2631 || data.backupMode == IApplicationThread.BACKUP_MODE_RESTORE_FULL)) {
2632 classname = "android.app.backup.FullBackupAgent";
2636 IBinder binder = null;
2637 BackupAgent agent = mBackupAgents.get(packageName);
2638 if (agent != null) {
2639 // reusing the existing instance
2641 Slog.v(TAG, "Reusing existing agent instance");
2643 binder = agent.onBind();
2646 if (DEBUG_BACKUP) Slog.v(TAG, "Initializing agent class " + classname);
2648 java.lang.ClassLoader cl = packageInfo.getClassLoader();
2649 agent = (BackupAgent) cl.loadClass(classname).newInstance();
2651 // set up the agent's context
2652 ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
2653 context.setOuterContext(agent);
2654 agent.attach(context);
2657 binder = agent.onBind();
2658 mBackupAgents.put(packageName, agent);
2659 } catch (Exception e) {
2660 // If this is during restore, fail silently; otherwise go
2661 // ahead and let the user see the crash.
2662 Slog.e(TAG, "Agent threw during creation: " + e);
2663 if (data.backupMode != IApplicationThread.BACKUP_MODE_RESTORE
2664 && data.backupMode != IApplicationThread.BACKUP_MODE_RESTORE_FULL) {
2667 // falling through with 'binder' still null
2671 // tell the OS that we're live now
2673 ActivityManagerNative.getDefault().backupAgentCreated(packageName, binder);
2674 } catch (RemoteException e) {
2677 } catch (Exception e) {
2678 throw new RuntimeException("Unable to create BackupAgent "
2679 + classname + ": " + e.toString(), e);
2683 // Tear down a BackupAgent
2684 private void handleDestroyBackupAgent(CreateBackupAgentData data) {
2685 if (DEBUG_BACKUP) Slog.v(TAG, "handleDestroyBackupAgent: " + data);
2687 LoadedApk packageInfo = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
2688 String packageName = packageInfo.mPackageName;
2689 BackupAgent agent = mBackupAgents.get(packageName);
2690 if (agent != null) {
2693 } catch (Exception e) {
2694 Slog.w(TAG, "Exception thrown in onDestroy by backup agent of " + data.appInfo);
2695 e.printStackTrace();
2697 mBackupAgents.remove(packageName);
2699 Slog.w(TAG, "Attempt to destroy unknown backup agent " + data);
2703 private void handleCreateService(CreateServiceData data) {
2704 // If we are getting ready to gc after going to the background, well
2705 // we are back active so skip it.
2706 unscheduleGcIdler();
2708 LoadedApk packageInfo = getPackageInfoNoCheck(
2709 data.info.applicationInfo, data.compatInfo);
2710 Service service = null;
2712 java.lang.ClassLoader cl = packageInfo.getClassLoader();
2713 service = (Service) cl.loadClass(data.info.name).newInstance();
2714 } catch (Exception e) {
2715 if (!mInstrumentation.onException(service, e)) {
2716 throw new RuntimeException(
2717 "Unable to instantiate service " + data.info.name
2718 + ": " + e.toString(), e);
2723 if (localLOGV) Slog.v(TAG, "Creating service " + data.info.name);
2725 ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
2726 context.setOuterContext(service);
2728 Application app = packageInfo.makeApplication(false, mInstrumentation);
2729 service.attach(context, this, data.info.name, data.token, app,
2730 ActivityManagerNative.getDefault());
2732 mServices.put(data.token, service);
2734 ActivityManagerNative.getDefault().serviceDoneExecuting(
2735 data.token, 0, 0, 0);
2736 } catch (RemoteException e) {
2739 } catch (Exception e) {
2740 if (!mInstrumentation.onException(service, e)) {
2741 throw new RuntimeException(
2742 "Unable to create service " + data.info.name
2743 + ": " + e.toString(), e);
2748 private void handleBindService(BindServiceData data) {
2749 Service s = mServices.get(data.token);
2751 Slog.v(TAG, "handleBindService s=" + s + " rebind=" + data.rebind);
2754 data.intent.setExtrasClassLoader(s.getClassLoader());
2755 data.intent.prepareToEnterProcess();
2758 IBinder binder = s.onBind(data.intent);
2759 ActivityManagerNative.getDefault().publishService(
2760 data.token, data.intent, binder);
2762 s.onRebind(data.intent);
2763 ActivityManagerNative.getDefault().serviceDoneExecuting(
2764 data.token, 0, 0, 0);
2767 } catch (RemoteException ex) {
2769 } catch (Exception e) {
2770 if (!mInstrumentation.onException(s, e)) {
2771 throw new RuntimeException(
2772 "Unable to bind to service " + s
2773 + " with " + data.intent + ": " + e.toString(), e);
2779 private void handleUnbindService(BindServiceData data) {
2780 Service s = mServices.get(data.token);
2783 data.intent.setExtrasClassLoader(s.getClassLoader());
2784 data.intent.prepareToEnterProcess();
2785 boolean doRebind = s.onUnbind(data.intent);
2788 ActivityManagerNative.getDefault().unbindFinished(
2789 data.token, data.intent, doRebind);
2791 ActivityManagerNative.getDefault().serviceDoneExecuting(
2792 data.token, 0, 0, 0);
2794 } catch (RemoteException ex) {
2796 } catch (Exception e) {
2797 if (!mInstrumentation.onException(s, e)) {
2798 throw new RuntimeException(
2799 "Unable to unbind to service " + s
2800 + " with " + data.intent + ": " + e.toString(), e);
2806 private void handleDumpService(DumpComponentInfo info) {
2807 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
2809 Service s = mServices.get(info.token);
2811 PrintWriter pw = new FastPrintWriter(new FileOutputStream(
2812 info.fd.getFileDescriptor()));
2813 s.dump(info.fd.getFileDescriptor(), pw, info.args);
2817 IoUtils.closeQuietly(info.fd);
2818 StrictMode.setThreadPolicy(oldPolicy);
2822 private void handleDumpActivity(DumpComponentInfo info) {
2823 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
2825 ActivityClientRecord r = mActivities.get(info.token);
2826 if (r != null && r.activity != null) {
2827 PrintWriter pw = new FastPrintWriter(new FileOutputStream(
2828 info.fd.getFileDescriptor()));
2829 r.activity.dump(info.prefix, info.fd.getFileDescriptor(), pw, info.args);
2833 IoUtils.closeQuietly(info.fd);
2834 StrictMode.setThreadPolicy(oldPolicy);
2838 private void handleDumpProvider(DumpComponentInfo info) {
2839 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
2841 ProviderClientRecord r = mLocalProviders.get(info.token);
2842 if (r != null && r.mLocalProvider != null) {
2843 PrintWriter pw = new FastPrintWriter(new FileOutputStream(
2844 info.fd.getFileDescriptor()));
2845 r.mLocalProvider.dump(info.fd.getFileDescriptor(), pw, info.args);
2849 IoUtils.closeQuietly(info.fd);
2850 StrictMode.setThreadPolicy(oldPolicy);
2854 private void handleServiceArgs(ServiceArgsData data) {
2855 Service s = mServices.get(data.token);
2858 if (data.args != null) {
2859 data.args.setExtrasClassLoader(s.getClassLoader());
2860 data.args.prepareToEnterProcess();
2863 if (!data.taskRemoved) {
2864 res = s.onStartCommand(data.args, data.flags, data.startId);
2866 s.onTaskRemoved(data.args);
2867 res = Service.START_TASK_REMOVED_COMPLETE;
2870 QueuedWork.waitToFinish();
2873 ActivityManagerNative.getDefault().serviceDoneExecuting(
2874 data.token, 1, data.startId, res);
2875 } catch (RemoteException e) {
2879 } catch (Exception e) {
2880 if (!mInstrumentation.onException(s, e)) {
2881 throw new RuntimeException(
2882 "Unable to start service " + s
2883 + " with " + data.args + ": " + e.toString(), e);
2889 private void handleStopService(IBinder token) {
2890 Service s = mServices.remove(token);
2893 if (localLOGV) Slog.v(TAG, "Destroying service " + s);
2895 Context context = s.getBaseContext();
2896 if (context instanceof ContextImpl) {
2897 final String who = s.getClassName();
2898 ((ContextImpl) context).scheduleFinalCleanup(who, "Service");
2901 QueuedWork.waitToFinish();
2904 ActivityManagerNative.getDefault().serviceDoneExecuting(
2906 } catch (RemoteException e) {
2909 } catch (Exception e) {
2910 if (!mInstrumentation.onException(s, e)) {
2911 throw new RuntimeException(
2912 "Unable to stop service " + s
2913 + ": " + e.toString(), e);
2917 //Slog.i(TAG, "Running services: " + mServices);
2920 public final ActivityClientRecord performResumeActivity(IBinder token,
2921 boolean clearHide) {
2922 ActivityClientRecord r = mActivities.get(token);
2923 if (localLOGV) Slog.v(TAG, "Performing resume of " + r
2924 + " finished=" + r.activity.mFinished);
2925 if (r != null && !r.activity.mFinished) {
2927 r.hideForNow = false;
2928 r.activity.mStartedActivity = false;
2931 r.activity.mFragments.noteStateNotSaved();
2932 if (r.pendingIntents != null) {
2933 deliverNewIntents(r, r.pendingIntents);
2934 r.pendingIntents = null;
2936 if (r.pendingResults != null) {
2937 deliverResults(r, r.pendingResults);
2938 r.pendingResults = null;
2940 r.activity.performResume();
2942 EventLog.writeEvent(LOG_ON_RESUME_CALLED,
2943 UserHandle.myUserId(), r.activity.getComponentName().getClassName());
2948 r.persistentState = null;
2949 } catch (Exception e) {
2950 if (!mInstrumentation.onException(r.activity, e)) {
2951 throw new RuntimeException(
2952 "Unable to resume activity "
2953 + r.intent.getComponent().toShortString()
2954 + ": " + e.toString(), e);
2961 static final void cleanUpPendingRemoveWindows(ActivityClientRecord r) {
2962 if (r.mPendingRemoveWindow != null) {
2963 r.mPendingRemoveWindowManager.removeViewImmediate(r.mPendingRemoveWindow);
2964 IBinder wtoken = r.mPendingRemoveWindow.getWindowToken();
2965 if (wtoken != null) {
2966 WindowManagerGlobal.getInstance().closeAll(wtoken,
2967 r.activity.getClass().getName(), "Activity");
2970 r.mPendingRemoveWindow = null;
2971 r.mPendingRemoveWindowManager = null;
2974 final void handleResumeActivity(IBinder token,
2975 boolean clearHide, boolean isForward, boolean reallyResume) {
2976 // If we are getting ready to gc after going to the background, well
2977 // we are back active so skip it.
2978 unscheduleGcIdler();
2979 mSomeActivitiesChanged = true;
2981 // TODO Push resumeArgs into the activity for consideration
2982 ActivityClientRecord r = performResumeActivity(token, clearHide);
2985 final Activity a = r.activity;
2987 if (localLOGV) Slog.v(
2988 TAG, "Resume " + r + " started activity: " +
2989 a.mStartedActivity + ", hideForNow: " + r.hideForNow
2990 + ", finished: " + a.mFinished);
2992 final int forwardBit = isForward ?
2993 WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION : 0;
2995 // If the window hasn't yet been added to the window manager,
2996 // and this guy didn't finish itself or start another activity,
2997 // then go ahead and add the window.
2998 boolean willBeVisible = !a.mStartedActivity;
2999 if (!willBeVisible) {
3001 willBeVisible = ActivityManagerNative.getDefault().willActivityBeVisible(
3002 a.getActivityToken());
3003 } catch (RemoteException e) {
3006 if (r.window == null && !a.mFinished && willBeVisible) {
3007 r.window = r.activity.getWindow();
3008 View decor = r.window.getDecorView();
3009 decor.setVisibility(View.INVISIBLE);
3010 ViewManager wm = a.getWindowManager();
3011 WindowManager.LayoutParams l = r.window.getAttributes();
3013 l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
3014 l.softInputMode |= forwardBit;
3015 if (a.mVisibleFromClient) {
3016 a.mWindowAdded = true;
3017 wm.addView(decor, l);
3020 // If the window has already been added, but during resume
3021 // we started another activity, then don't yet make the
3023 } else if (!willBeVisible) {
3024 if (localLOGV) Slog.v(
3025 TAG, "Launch " + r + " mStartedActivity set");
3026 r.hideForNow = true;
3029 // Get rid of anything left hanging around.
3030 cleanUpPendingRemoveWindows(r);
3032 // The window is now visible if it has been added, we are not
3033 // simply finishing, and we are not starting another activity.
3034 if (!r.activity.mFinished && willBeVisible
3035 && r.activity.mDecor != null && !r.hideForNow) {
3036 if (r.newConfig != null) {
3037 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Resuming activity "
3038 + r.activityInfo.name + " with newConfig " + r.newConfig);
3039 performConfigurationChanged(r.activity, r.newConfig);
3040 freeTextLayoutCachesIfNeeded(r.activity.mCurrentConfig.diff(r.newConfig));
3043 if (localLOGV) Slog.v(TAG, "Resuming " + r + " with isForward="
3045 WindowManager.LayoutParams l = r.window.getAttributes();
3046 if ((l.softInputMode
3047 & WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION)
3049 l.softInputMode = (l.softInputMode
3050 & (~WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION))
3052 if (r.activity.mVisibleFromClient) {
3053 ViewManager wm = a.getWindowManager();
3054 View decor = r.window.getDecorView();
3055 wm.updateViewLayout(decor, l);
3058 r.activity.mVisibleFromServer = true;
3059 mNumVisibleActivities++;
3060 if (r.activity.mVisibleFromClient) {
3061 r.activity.makeVisible();
3065 if (!r.onlyLocalRequest) {
3066 r.nextIdle = mNewActivities;
3068 if (localLOGV) Slog.v(
3069 TAG, "Scheduling idle handler for " + r);
3070 Looper.myQueue().addIdleHandler(new Idler());
3072 r.onlyLocalRequest = false;
3074 // Tell the activity manager we have resumed.
3077 ActivityManagerNative.getDefault().activityResumed(token);
3078 } catch (RemoteException ex) {
3083 // If an exception was thrown when trying to resume, then
3084 // just end this activity.
3086 ActivityManagerNative.getDefault()
3087 .finishActivity(token, Activity.RESULT_CANCELED, null, false);
3088 } catch (RemoteException ex) {
3093 private int mThumbnailWidth = -1;
3094 private int mThumbnailHeight = -1;
3095 private Bitmap mAvailThumbnailBitmap = null;
3096 private Canvas mThumbnailCanvas = null;
3098 private Bitmap createThumbnailBitmap(ActivityClientRecord r) {
3099 Bitmap thumbnail = mAvailThumbnailBitmap;
3101 if (thumbnail == null) {
3102 int w = mThumbnailWidth;
3105 Resources res = r.activity.getResources();
3106 int wId = com.android.internal.R.dimen.thumbnail_width;
3107 int hId = com.android.internal.R.dimen.thumbnail_height;
3108 mThumbnailWidth = w = res.getDimensionPixelSize(wId);
3109 mThumbnailHeight = h = res.getDimensionPixelSize(hId);
3111 h = mThumbnailHeight;
3114 // On platforms where we don't want thumbnails, set dims to (0,0)
3115 if ((w > 0) && (h > 0)) {
3116 thumbnail = Bitmap.createBitmap(r.activity.getResources().getDisplayMetrics(),
3117 w, h, THUMBNAIL_FORMAT);
3118 thumbnail.eraseColor(0);
3122 if (thumbnail != null) {
3123 Canvas cv = mThumbnailCanvas;
3125 mThumbnailCanvas = cv = new Canvas();
3128 cv.setBitmap(thumbnail);
3129 if (!r.activity.onCreateThumbnail(thumbnail, cv)) {
3130 mAvailThumbnailBitmap = thumbnail;
3136 } catch (Exception e) {
3137 if (!mInstrumentation.onException(r.activity, e)) {
3138 throw new RuntimeException(
3139 "Unable to create thumbnail of "
3140 + r.intent.getComponent().toShortString()
3141 + ": " + e.toString(), e);
3149 private void handlePauseActivity(IBinder token, boolean finished,
3150 boolean userLeaving, int configChanges, boolean dontReport) {
3151 ActivityClientRecord r = mActivities.get(token);
3153 //Slog.v(TAG, "userLeaving=" + userLeaving + " handling pause of " + r);
3155 performUserLeavingActivity(r);
3158 r.activity.mConfigChangeFlags |= configChanges;
3159 performPauseActivity(token, finished, r.isPreHoneycomb());
3161 // Make sure any pending writes are now committed.
3162 if (r.isPreHoneycomb()) {
3163 QueuedWork.waitToFinish();
3166 // Tell the activity manager we have paused.
3169 ActivityManagerNative.getDefault().activityPaused(token);
3170 } catch (RemoteException ex) {
3173 mSomeActivitiesChanged = true;
3177 final void performUserLeavingActivity(ActivityClientRecord r) {
3178 mInstrumentation.callActivityOnUserLeaving(r.activity);
3181 final Bundle performPauseActivity(IBinder token, boolean finished,
3182 boolean saveState) {
3183 ActivityClientRecord r = mActivities.get(token);
3184 return r != null ? performPauseActivity(r, finished, saveState) : null;
3187 final Bundle performPauseActivity(ActivityClientRecord r, boolean finished,
3188 boolean saveState) {
3190 if (r.activity.mFinished) {
3191 // If we are finishing, we won't call onResume() in certain cases.
3192 // So here we likewise don't want to call onPause() if the activity
3196 RuntimeException e = new RuntimeException(
3197 "Performing pause of activity that is not resumed: "
3198 + r.intent.getComponent().toShortString());
3199 Slog.e(TAG, e.getMessage(), e);
3202 r.activity.mFinished = true;
3205 // Next have the activity save its current state and managed dialogs...
3206 if (!r.activity.mFinished && saveState) {
3207 callCallActivityOnSaveInstanceState(r);
3210 r.activity.mCalled = false;
3211 mInstrumentation.callActivityOnPause(r.activity);
3212 EventLog.writeEvent(LOG_ON_PAUSE_CALLED, UserHandle.myUserId(),
3213 r.activity.getComponentName().getClassName());
3214 if (!r.activity.mCalled) {
3215 throw new SuperNotCalledException(
3216 "Activity " + r.intent.getComponent().toShortString() +
3217 " did not call through to super.onPause()");
3220 } catch (SuperNotCalledException e) {
3223 } catch (Exception e) {
3224 if (!mInstrumentation.onException(r.activity, e)) {
3225 throw new RuntimeException(
3226 "Unable to pause activity "
3227 + r.intent.getComponent().toShortString()
3228 + ": " + e.toString(), e);
3233 // Notify any outstanding on paused listeners
3234 ArrayList<OnActivityPausedListener> listeners;
3235 synchronized (mOnPauseListeners) {
3236 listeners = mOnPauseListeners.remove(r.activity);
3238 int size = (listeners != null ? listeners.size() : 0);
3239 for (int i = 0; i < size; i++) {
3240 listeners.get(i).onPaused(r.activity);
3243 return !r.activity.mFinished && saveState ? r.state : null;
3246 final void performStopActivity(IBinder token, boolean saveState) {
3247 ActivityClientRecord r = mActivities.get(token);
3248 performStopActivityInner(r, null, false, saveState);
3251 private static class StopInfo implements Runnable {
3252 ActivityClientRecord activity;
3254 PersistableBundle persistentState;
3255 CharSequence description;
3257 @Override public void run() {
3258 // Tell activity manager we have been stopped.
3260 if (DEBUG_MEMORY_TRIM) Slog.v(TAG, "Reporting activity stopped: " + activity);
3261 ActivityManagerNative.getDefault().activityStopped(
3262 activity.token, state, persistentState, description);
3263 } catch (RemoteException ex) {
3268 private static final class ProviderRefCount {
3269 public final IActivityManager.ContentProviderHolder holder;
3270 public final ProviderClientRecord client;
3271 public int stableCount;
3272 public int unstableCount;
3274 // When this is set, the stable and unstable ref counts are 0 and
3275 // we have a pending operation scheduled to remove the ref count
3276 // from the activity manager. On the activity manager we are still
3277 // holding an unstable ref, though it is not reflected in the counts
3279 public boolean removePending;
3281 ProviderRefCount(IActivityManager.ContentProviderHolder inHolder,
3282 ProviderClientRecord inClient, int sCount, int uCount) {
3285 stableCount = sCount;
3286 unstableCount = uCount;
3291 * Core implementation of stopping an activity. Note this is a little
3292 * tricky because the server's meaning of stop is slightly different
3293 * than our client -- for the server, stop means to save state and give
3294 * it the result when it is done, but the window may still be visible.
3295 * For the client, we want to call onStop()/onStart() to indicate when
3296 * the activity's UI visibillity changes.
3298 private void performStopActivityInner(ActivityClientRecord r,
3299 StopInfo info, boolean keepShown, boolean saveState) {
3300 if (localLOGV) Slog.v(TAG, "Performing stop of " + r);
3302 if (!keepShown && r.stopped) {
3303 if (r.activity.mFinished) {
3304 // If we are finishing, we won't call onResume() in certain
3305 // cases. So here we likewise don't want to call onStop()
3306 // if the activity isn't resumed.
3309 RuntimeException e = new RuntimeException(
3310 "Performing stop of activity that is not resumed: "
3311 + r.intent.getComponent().toShortString());
3312 Slog.e(TAG, e.getMessage(), e);
3317 // First create a thumbnail for the activity...
3318 // For now, don't create the thumbnail here; we are
3319 // doing that by doing a screen snapshot.
3320 info.description = r.activity.onCreateDescription();
3321 } catch (Exception e) {
3322 if (!mInstrumentation.onException(r.activity, e)) {
3323 throw new RuntimeException(
3324 "Unable to save state of activity "
3325 + r.intent.getComponent().toShortString()
3326 + ": " + e.toString(), e);
3331 // Next have the activity save its current state and managed dialogs...
3332 if (!r.activity.mFinished && saveState) {
3333 if (r.state == null) {
3334 callCallActivityOnSaveInstanceState(r);
3341 r.activity.performStop();
3342 } catch (Exception e) {
3343 if (!mInstrumentation.onException(r.activity, e)) {
3344 throw new RuntimeException(
3345 "Unable to stop activity "
3346 + r.intent.getComponent().toShortString()
3347 + ": " + e.toString(), e);
3357 private void updateVisibility(ActivityClientRecord r, boolean show) {
3358 View v = r.activity.mDecor;
3361 if (!r.activity.mVisibleFromServer) {
3362 r.activity.mVisibleFromServer = true;
3363 mNumVisibleActivities++;
3364 if (r.activity.mVisibleFromClient) {
3365 r.activity.makeVisible();
3368 if (r.newConfig != null) {
3369 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Updating activity vis "
3370 + r.activityInfo.name + " with new config " + r.newConfig);
3371 performConfigurationChanged(r.activity, r.newConfig);
3372 freeTextLayoutCachesIfNeeded(r.activity.mCurrentConfig.diff(r.newConfig));
3376 if (r.activity.mVisibleFromServer) {
3377 r.activity.mVisibleFromServer = false;
3378 mNumVisibleActivities--;
3379 v.setVisibility(View.INVISIBLE);
3385 private void handleStopActivity(IBinder token, boolean show, int configChanges) {
3386 ActivityClientRecord r = mActivities.get(token);
3387 r.activity.mConfigChangeFlags |= configChanges;
3389 StopInfo info = new StopInfo();
3390 performStopActivityInner(r, info, show, true);
3392 if (localLOGV) Slog.v(
3393 TAG, "Finishing stop of " + r + ": show=" + show
3394 + " win=" + r.window);
3396 updateVisibility(r, show);
3398 // Make sure any pending writes are now committed.
3399 if (!r.isPreHoneycomb()) {
3400 QueuedWork.waitToFinish();
3403 // Schedule the call to tell the activity manager we have
3404 // stopped. We don't do this immediately, because we want to
3405 // have a chance for any other pending work (in particular memory
3406 // trim requests) to complete before you tell the activity
3407 // manager to proceed and allow us to go fully into the background.
3409 info.state = r.state;
3410 info.persistentState = r.persistentState;
3412 mSomeActivitiesChanged = true;
3415 final void performRestartActivity(IBinder token) {
3416 ActivityClientRecord r = mActivities.get(token);
3418 r.activity.performRestart();
3423 private void handleWindowVisibility(IBinder token, boolean show) {
3424 ActivityClientRecord r = mActivities.get(token);
3427 Log.w(TAG, "handleWindowVisibility: no activity for token " + token);
3431 if (!show && !r.stopped) {
3432 performStopActivityInner(r, null, show, false);
3433 } else if (show && r.stopped) {
3434 // If we are getting ready to gc after going to the background, well
3435 // we are back active so skip it.
3436 unscheduleGcIdler();
3438 r.activity.performRestart();
3441 if (r.activity.mDecor != null) {
3443 TAG, "Handle window " + r + " visibility: " + show);
3444 updateVisibility(r, show);
3446 mSomeActivitiesChanged = true;
3449 private void handleSleeping(IBinder token, boolean sleeping) {
3450 ActivityClientRecord r = mActivities.get(token);
3453 Log.w(TAG, "handleSleeping: no activity for token " + token);
3458 if (!r.stopped && !r.isPreHoneycomb()) {
3461 r.activity.performStop();
3462 } catch (Exception e) {
3463 if (!mInstrumentation.onException(r.activity, e)) {
3464 throw new RuntimeException(
3465 "Unable to stop activity "
3466 + r.intent.getComponent().toShortString()
3467 + ": " + e.toString(), e);
3473 // Make sure any pending writes are now committed.
3474 if (!r.isPreHoneycomb()) {
3475 QueuedWork.waitToFinish();
3478 // Tell activity manager we slept.
3480 ActivityManagerNative.getDefault().activitySlept(r.token);
3481 } catch (RemoteException ex) {
3484 if (r.stopped && r.activity.mVisibleFromServer) {
3485 r.activity.performRestart();
3491 private void handleSetCoreSettings(Bundle coreSettings) {
3492 synchronized (mResourcesManager) {
3493 mCoreSettings = coreSettings;
3495 onCoreSettingsChange();
3498 private void onCoreSettingsChange() {
3499 boolean debugViewAttributes =
3500 mCoreSettings.getInt(Settings.Global.DEBUG_VIEW_ATTRIBUTES, 0) != 0;
3501 if (debugViewAttributes != View.mDebugViewAttributes) {
3502 View.mDebugViewAttributes = debugViewAttributes;
3504 // request all activities to relaunch for the changes to take place
3505 for (Map.Entry<IBinder, ActivityClientRecord> entry : mActivities.entrySet()) {
3506 requestRelaunchActivity(entry.getKey(), null, null, 0, false, null, false);
3511 private void handleUpdatePackageCompatibilityInfo(UpdateCompatibilityData data) {
3512 LoadedApk apk = peekPackageInfo(data.pkg, false);
3514 apk.setCompatibilityInfo(data.info);
3516 apk = peekPackageInfo(data.pkg, true);
3518 apk.setCompatibilityInfo(data.info);
3520 handleConfigurationChanged(mConfiguration, data.info);
3521 WindowManagerGlobal.getInstance().reportNewConfiguration(mConfiguration);
3524 private void deliverResults(ActivityClientRecord r, List<ResultInfo> results) {
3525 final int N = results.size();
3526 for (int i=0; i<N; i++) {
3527 ResultInfo ri = results.get(i);
3529 if (ri.mData != null) {
3530 ri.mData.setExtrasClassLoader(r.activity.getClassLoader());
3531 ri.mData.prepareToEnterProcess();
3533 if (DEBUG_RESULTS) Slog.v(TAG,
3534 "Delivering result to activity " + r + " : " + ri);
3535 r.activity.dispatchActivityResult(ri.mResultWho,
3536 ri.mRequestCode, ri.mResultCode, ri.mData);
3537 } catch (Exception e) {
3538 if (!mInstrumentation.onException(r.activity, e)) {
3539 throw new RuntimeException(
3540 "Failure delivering result " + ri + " to activity "
3541 + r.intent.getComponent().toShortString()
3542 + ": " + e.toString(), e);
3548 private void handleSendResult(ResultData res) {
3549 ActivityClientRecord r = mActivities.get(res.token);
3550 if (DEBUG_RESULTS) Slog.v(TAG, "Handling send result to " + r);
3552 final boolean resumed = !r.paused;
3553 if (!r.activity.mFinished && r.activity.mDecor != null
3554 && r.hideForNow && resumed) {
3555 // We had hidden the activity because it started another
3556 // one... we have gotten a result back and we are not
3557 // paused, so make sure our window is visible.
3558 updateVisibility(r, true);
3563 r.activity.mCalled = false;
3564 r.activity.mTemporaryPause = true;
3565 mInstrumentation.callActivityOnPause(r.activity);
3566 if (!r.activity.mCalled) {
3567 throw new SuperNotCalledException(
3568 "Activity " + r.intent.getComponent().toShortString()
3569 + " did not call through to super.onPause()");
3571 } catch (SuperNotCalledException e) {
3573 } catch (Exception e) {
3574 if (!mInstrumentation.onException(r.activity, e)) {
3575 throw new RuntimeException(
3576 "Unable to pause activity "
3577 + r.intent.getComponent().toShortString()
3578 + ": " + e.toString(), e);
3582 deliverResults(r, res.results);
3584 r.activity.performResume();
3585 r.activity.mTemporaryPause = false;
3590 public final ActivityClientRecord performDestroyActivity(IBinder token, boolean finishing) {
3591 return performDestroyActivity(token, finishing, 0, false);
3594 private ActivityClientRecord performDestroyActivity(IBinder token, boolean finishing,
3595 int configChanges, boolean getNonConfigInstance) {
3596 ActivityClientRecord r = mActivities.get(token);
3597 Class<? extends Activity> activityClass = null;
3598 if (localLOGV) Slog.v(TAG, "Performing finish of " + r);
3600 activityClass = r.activity.getClass();
3601 r.activity.mConfigChangeFlags |= configChanges;
3603 r.activity.mFinished = true;
3607 r.activity.mCalled = false;
3608 mInstrumentation.callActivityOnPause(r.activity);
3609 EventLog.writeEvent(LOG_ON_PAUSE_CALLED, UserHandle.myUserId(),
3610 r.activity.getComponentName().getClassName());
3611 if (!r.activity.mCalled) {
3612 throw new SuperNotCalledException(
3613 "Activity " + safeToComponentShortString(r.intent)
3614 + " did not call through to super.onPause()");
3616 } catch (SuperNotCalledException e) {
3618 } catch (Exception e) {
3619 if (!mInstrumentation.onException(r.activity, e)) {
3620 throw new RuntimeException(
3621 "Unable to pause activity "
3622 + safeToComponentShortString(r.intent)
3623 + ": " + e.toString(), e);
3630 r.activity.performStop();
3631 } catch (SuperNotCalledException e) {
3633 } catch (Exception e) {
3634 if (!mInstrumentation.onException(r.activity, e)) {
3635 throw new RuntimeException(
3636 "Unable to stop activity "
3637 + safeToComponentShortString(r.intent)
3638 + ": " + e.toString(), e);
3643 if (getNonConfigInstance) {
3645 r.lastNonConfigurationInstances
3646 = r.activity.retainNonConfigurationInstances();
3647 } catch (Exception e) {
3648 if (!mInstrumentation.onException(r.activity, e)) {
3649 throw new RuntimeException(
3650 "Unable to retain activity "
3651 + r.intent.getComponent().toShortString()
3652 + ": " + e.toString(), e);
3657 r.activity.mCalled = false;
3658 mInstrumentation.callActivityOnDestroy(r.activity);
3659 if (!r.activity.mCalled) {
3660 throw new SuperNotCalledException(
3661 "Activity " + safeToComponentShortString(r.intent) +
3662 " did not call through to super.onDestroy()");
3664 if (r.window != null) {
3665 r.window.closeAllPanels();
3667 } catch (SuperNotCalledException e) {
3669 } catch (Exception e) {
3670 if (!mInstrumentation.onException(r.activity, e)) {
3671 throw new RuntimeException(
3672 "Unable to destroy activity " + safeToComponentShortString(r.intent)
3673 + ": " + e.toString(), e);
3677 mActivities.remove(token);
3678 StrictMode.decrementExpectedActivityCount(activityClass);
3682 private static String safeToComponentShortString(Intent intent) {
3683 ComponentName component = intent.getComponent();
3684 return component == null ? "[Unknown]" : component.toShortString();
3687 private void handleDestroyActivity(IBinder token, boolean finishing,
3688 int configChanges, boolean getNonConfigInstance) {
3689 ActivityClientRecord r = performDestroyActivity(token, finishing,
3690 configChanges, getNonConfigInstance);
3692 cleanUpPendingRemoveWindows(r);
3693 WindowManager wm = r.activity.getWindowManager();
3694 View v = r.activity.mDecor;
3696 if (r.activity.mVisibleFromServer) {
3697 mNumVisibleActivities--;
3699 IBinder wtoken = v.getWindowToken();
3700 if (r.activity.mWindowAdded) {
3701 if (r.onlyLocalRequest) {
3702 // Hold off on removing this until the new activity's
3703 // window is being added.
3704 r.mPendingRemoveWindow = v;
3705 r.mPendingRemoveWindowManager = wm;
3707 wm.removeViewImmediate(v);
3710 if (wtoken != null && r.mPendingRemoveWindow == null) {
3711 WindowManagerGlobal.getInstance().closeAll(wtoken,
3712 r.activity.getClass().getName(), "Activity");
3714 r.activity.mDecor = null;
3716 if (r.mPendingRemoveWindow == null) {
3717 // If we are delaying the removal of the activity window, then
3718 // we can't clean up all windows here. Note that we can't do
3719 // so later either, which means any windows that aren't closed
3720 // by the app will leak. Well we try to warning them a lot
3721 // about leaking windows, because that is a bug, so if they are
3722 // using this recreate facility then they get to live with leaks.
3723 WindowManagerGlobal.getInstance().closeAll(token,
3724 r.activity.getClass().getName(), "Activity");
3727 // Mocked out contexts won't be participating in the normal
3728 // process lifecycle, but if we're running with a proper
3729 // ApplicationContext we need to have it tear down things
3731 Context c = r.activity.getBaseContext();
3732 if (c instanceof ContextImpl) {
3733 ((ContextImpl) c).scheduleFinalCleanup(
3734 r.activity.getClass().getName(), "Activity");
3739 ActivityManagerNative.getDefault().activityDestroyed(token);
3740 } catch (RemoteException ex) {
3741 // If the system process has died, it's game over for everyone.
3744 mSomeActivitiesChanged = true;
3747 public final void requestRelaunchActivity(IBinder token,
3748 List<ResultInfo> pendingResults, List<Intent> pendingNewIntents,
3749 int configChanges, boolean notResumed, Configuration config,
3750 boolean fromServer) {
3751 ActivityClientRecord target = null;
3753 synchronized (mResourcesManager) {
3754 for (int i=0; i<mRelaunchingActivities.size(); i++) {
3755 ActivityClientRecord r = mRelaunchingActivities.get(i);
3756 if (r.token == token) {
3758 if (pendingResults != null) {
3759 if (r.pendingResults != null) {
3760 r.pendingResults.addAll(pendingResults);
3762 r.pendingResults = pendingResults;
3765 if (pendingNewIntents != null) {
3766 if (r.pendingIntents != null) {
3767 r.pendingIntents.addAll(pendingNewIntents);
3769 r.pendingIntents = pendingNewIntents;
3776 if (target == null) {
3777 target = new ActivityClientRecord();
3778 target.token = token;
3779 target.pendingResults = pendingResults;
3780 target.pendingIntents = pendingNewIntents;
3782 ActivityClientRecord existing = mActivities.get(token);
3783 if (existing != null) {
3784 target.startsNotResumed = existing.paused;
3786 target.onlyLocalRequest = true;
3788 mRelaunchingActivities.add(target);
3789 sendMessage(H.RELAUNCH_ACTIVITY, target);
3793 target.startsNotResumed = notResumed;
3794 target.onlyLocalRequest = false;
3796 if (config != null) {
3797 target.createdConfig = config;
3799 target.pendingConfigChanges |= configChanges;
3803 private void handleRelaunchActivity(ActivityClientRecord tmp) {
3804 // If we are getting ready to gc after going to the background, well
3805 // we are back active so skip it.
3806 unscheduleGcIdler();
3807 mSomeActivitiesChanged = true;
3809 Configuration changedConfig = null;
3810 int configChanges = 0;
3812 // First: make sure we have the most recent configuration and most
3813 // recent version of the activity, or skip it if some previous call
3814 // had taken a more recent version.
3815 synchronized (mResourcesManager) {
3816 int N = mRelaunchingActivities.size();
3817 IBinder token = tmp.token;
3819 for (int i=0; i<N; i++) {
3820 ActivityClientRecord r = mRelaunchingActivities.get(i);
3821 if (r.token == token) {
3823 configChanges |= tmp.pendingConfigChanges;
3824 mRelaunchingActivities.remove(i);
3831 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Abort, activity not relaunching!");
3835 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Relaunching activity "
3836 + tmp.token + " with configChanges=0x"
3837 + Integer.toHexString(configChanges));
3839 if (mPendingConfiguration != null) {
3840 changedConfig = mPendingConfiguration;
3841 mPendingConfiguration = null;
3845 if (tmp.createdConfig != null) {
3846 // If the activity manager is passing us its current config,
3847 // assume that is really what we want regardless of what we
3848 // may have pending.
3849 if (mConfiguration == null
3850 || (tmp.createdConfig.isOtherSeqNewer(mConfiguration)
3851 && mConfiguration.diff(tmp.createdConfig) != 0)) {
3852 if (changedConfig == null
3853 || tmp.createdConfig.isOtherSeqNewer(changedConfig)) {
3854 changedConfig = tmp.createdConfig;
3859 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Relaunching activity "
3860 + tmp.token + ": changedConfig=" + changedConfig);
3862 // If there was a pending configuration change, execute it first.
3863 if (changedConfig != null) {
3864 mCurDefaultDisplayDpi = changedConfig.densityDpi;
3865 updateDefaultDensity();
3866 handleConfigurationChanged(changedConfig, null);
3869 ActivityClientRecord r = mActivities.get(tmp.token);
3870 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handling relaunch of " + r);
3875 r.activity.mConfigChangeFlags |= configChanges;
3876 r.onlyLocalRequest = tmp.onlyLocalRequest;
3877 Intent currentIntent = r.activity.mIntent;
3879 r.activity.mChangingConfigurations = true;
3881 // Need to ensure state is saved.
3883 performPauseActivity(r.token, false, r.isPreHoneycomb());
3885 if (r.state == null && !r.stopped && !r.isPreHoneycomb()) {
3886 callCallActivityOnSaveInstanceState(r);
3889 handleDestroyActivity(r.token, false, configChanges, true);
3893 r.hideForNow = false;
3895 // Merge any pending results and pending intents; don't just replace them
3896 if (tmp.pendingResults != null) {
3897 if (r.pendingResults == null) {
3898 r.pendingResults = tmp.pendingResults;
3900 r.pendingResults.addAll(tmp.pendingResults);
3903 if (tmp.pendingIntents != null) {
3904 if (r.pendingIntents == null) {
3905 r.pendingIntents = tmp.pendingIntents;
3907 r.pendingIntents.addAll(tmp.pendingIntents);
3910 r.startsNotResumed = tmp.startsNotResumed;
3912 handleLaunchActivity(r, currentIntent);
3915 private void callCallActivityOnSaveInstanceState(ActivityClientRecord r) {
3916 r.state = new Bundle();
3917 r.state.setAllowFds(false);
3918 if (r.isPersistable()) {
3919 r.persistentState = new PersistableBundle();
3920 mInstrumentation.callActivityOnSaveInstanceState(r.activity, r.state,
3923 mInstrumentation.callActivityOnSaveInstanceState(r.activity, r.state);
3927 ArrayList<ComponentCallbacks2> collectComponentCallbacks(
3928 boolean allActivities, Configuration newConfig) {
3929 ArrayList<ComponentCallbacks2> callbacks
3930 = new ArrayList<ComponentCallbacks2>();
3932 synchronized (mResourcesManager) {
3933 final int NAPP = mAllApplications.size();
3934 for (int i=0; i<NAPP; i++) {
3935 callbacks.add(mAllApplications.get(i));
3937 final int NACT = mActivities.size();
3938 for (int i=0; i<NACT; i++) {
3939 ActivityClientRecord ar = mActivities.valueAt(i);
3940 Activity a = ar.activity;
3942 Configuration thisConfig = applyConfigCompatMainThread(
3943 mCurDefaultDisplayDpi, newConfig,
3944 ar.packageInfo.getCompatibilityInfo());
3945 if (!ar.activity.mFinished && (allActivities || !ar.paused)) {
3946 // If the activity is currently resumed, its configuration
3947 // needs to change right now.
3949 } else if (thisConfig != null) {
3950 // Otherwise, we will tell it about the change
3951 // the next time it is resumed or shown. Note that
3952 // the activity manager may, before then, decide the
3953 // activity needs to be destroyed to handle its new
3955 if (DEBUG_CONFIGURATION) {
3956 Slog.v(TAG, "Setting activity "
3957 + ar.activityInfo.name + " newConfig=" + thisConfig);
3959 ar.newConfig = thisConfig;
3963 final int NSVC = mServices.size();
3964 for (int i=0; i<NSVC; i++) {
3965 callbacks.add(mServices.valueAt(i));
3968 synchronized (mProviderMap) {
3969 final int NPRV = mLocalProviders.size();
3970 for (int i=0; i<NPRV; i++) {
3971 callbacks.add(mLocalProviders.valueAt(i).mLocalProvider);
3978 private static void performConfigurationChanged(ComponentCallbacks2 cb, Configuration config) {
3979 // Only for Activity objects, check that they actually call up to their
3980 // superclass implementation. ComponentCallbacks2 is an interface, so
3981 // we check the runtime type and act accordingly.
3982 Activity activity = (cb instanceof Activity) ? (Activity) cb : null;
3983 if (activity != null) {
3984 activity.mCalled = false;
3987 boolean shouldChangeConfig = false;
3988 if ((activity == null) || (activity.mCurrentConfig == null)) {
3989 shouldChangeConfig = true;
3992 // If the new config is the same as the config this Activity
3993 // is already running with then don't bother calling
3994 // onConfigurationChanged
3995 int diff = activity.mCurrentConfig.diff(config);
3997 // If this activity doesn't handle any of the config changes
3998 // then don't bother calling onConfigurationChanged as we're
3999 // going to destroy it.
4000 if ((~activity.mActivityInfo.getRealConfigChanged() & diff) == 0) {
4001 shouldChangeConfig = true;
4006 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Config callback " + cb
4007 + ": shouldChangeConfig=" + shouldChangeConfig);
4008 if (shouldChangeConfig) {
4009 cb.onConfigurationChanged(config);
4011 if (activity != null) {
4012 if (!activity.mCalled) {
4013 throw new SuperNotCalledException(
4014 "Activity " + activity.getLocalClassName() +
4015 " did not call through to super.onConfigurationChanged()");
4017 activity.mConfigChangeFlags = 0;
4018 activity.mCurrentConfig = new Configuration(config);
4023 public final void applyConfigurationToResources(Configuration config) {
4024 synchronized (mResourcesManager) {
4025 mResourcesManager.applyConfigurationToResourcesLocked(config, null);
4029 final Configuration applyCompatConfiguration(int displayDensity) {
4030 Configuration config = mConfiguration;
4031 if (mCompatConfiguration == null) {
4032 mCompatConfiguration = new Configuration();
4034 mCompatConfiguration.setTo(mConfiguration);
4035 if (mResourcesManager.applyCompatConfiguration(displayDensity, mCompatConfiguration)) {
4036 config = mCompatConfiguration;
4041 final void handleConfigurationChanged(Configuration config, CompatibilityInfo compat) {
4045 synchronized (mResourcesManager) {
4046 if (mPendingConfiguration != null) {
4047 if (!mPendingConfiguration.isOtherSeqNewer(config)) {
4048 config = mPendingConfiguration;
4049 mCurDefaultDisplayDpi = config.densityDpi;
4050 updateDefaultDensity();
4052 mPendingConfiguration = null;
4055 if (config == null) {
4059 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handle configuration changed: "
4062 mResourcesManager.applyConfigurationToResourcesLocked(config, compat);
4064 if (mConfiguration == null) {
4065 mConfiguration = new Configuration();
4067 if (!mConfiguration.isOtherSeqNewer(config) && compat == null) {
4070 configDiff = mConfiguration.diff(config);
4071 mConfiguration.updateFrom(config);
4072 config = applyCompatConfiguration(mCurDefaultDisplayDpi);
4075 ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(false, config);
4077 freeTextLayoutCachesIfNeeded(configDiff);
4079 if (callbacks != null) {
4080 final int N = callbacks.size();
4081 for (int i=0; i<N; i++) {
4082 performConfigurationChanged(callbacks.get(i), config);
4087 static void freeTextLayoutCachesIfNeeded(int configDiff) {
4088 if (configDiff != 0) {
4089 // Ask text layout engine to free its caches if there is a locale change
4090 boolean hasLocaleConfigChange = ((configDiff & ActivityInfo.CONFIG_LOCALE) != 0);
4091 if (hasLocaleConfigChange) {
4092 Canvas.freeTextLayoutCaches();
4093 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Cleared TextLayout Caches");
4098 final void handleActivityConfigurationChanged(IBinder token) {
4099 ActivityClientRecord r = mActivities.get(token);
4100 if (r == null || r.activity == null) {
4104 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handle activity config changed: "
4105 + r.activityInfo.name);
4107 performConfigurationChanged(r.activity, mCompatConfiguration);
4109 freeTextLayoutCachesIfNeeded(r.activity.mCurrentConfig.diff(mCompatConfiguration));
4111 mSomeActivitiesChanged = true;
4114 final void handleProfilerControl(boolean start, ProfilerInfo profilerInfo, int profileType) {
4117 switch (profileType) {
4119 mProfiler.setProfiler(profilerInfo);
4120 mProfiler.startProfiling();
4123 } catch (RuntimeException e) {
4124 Slog.w(TAG, "Profiling failed on path " + profilerInfo.profileFile
4125 + " -- can the process access this path?");
4128 profilerInfo.profileFd.close();
4129 } catch (IOException e) {
4130 Slog.w(TAG, "Failure closing profile fd", e);
4134 switch (profileType) {
4136 mProfiler.stopProfiling();
4142 static final void handleDumpHeap(boolean managed, DumpHeapData dhd) {
4145 Debug.dumpHprofData(dhd.path, dhd.fd.getFileDescriptor());
4146 } catch (IOException e) {
4147 Slog.w(TAG, "Managed heap dump failed on path " + dhd.path
4148 + " -- can the process access this path?");
4152 } catch (IOException e) {
4153 Slog.w(TAG, "Failure closing profile fd", e);
4157 Debug.dumpNativeHeap(dhd.fd.getFileDescriptor());
4161 final void handleDispatchPackageBroadcast(int cmd, String[] packages) {
4162 boolean hasPkgInfo = false;
4163 if (packages != null) {
4164 for (int i=packages.length-1; i>=0; i--) {
4165 //Slog.i(TAG, "Cleaning old package: " + packages[i]);
4167 WeakReference<LoadedApk> ref;
4168 ref = mPackages.get(packages[i]);
4169 if (ref != null && ref.get() != null) {
4172 ref = mResourcePackages.get(packages[i]);
4173 if (ref != null && ref.get() != null) {
4178 mPackages.remove(packages[i]);
4179 mResourcePackages.remove(packages[i]);
4182 ApplicationPackageManager.handlePackageBroadcast(cmd, packages,
4186 final void handleLowMemory() {
4187 ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(true, null);
4189 final int N = callbacks.size();
4190 for (int i=0; i<N; i++) {
4191 callbacks.get(i).onLowMemory();
4194 // Ask SQLite to free up as much memory as it can, mostly from its page caches.
4195 if (Process.myUid() != Process.SYSTEM_UID) {
4196 int sqliteReleased = SQLiteDatabase.releaseMemory();
4197 EventLog.writeEvent(SQLITE_MEM_RELEASED_EVENT_LOG_TAG, sqliteReleased);
4200 // Ask graphics to free up as much as possible (font/image caches)
4201 Canvas.freeCaches();
4203 // Ask text layout engine to free also as much as possible
4204 Canvas.freeTextLayoutCaches();
4206 BinderInternal.forceGc("mem");
4209 final void handleTrimMemory(int level) {
4210 if (DEBUG_MEMORY_TRIM) Slog.v(TAG, "Trimming memory to level: " + level);
4212 ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(true, null);
4214 final int N = callbacks.size();
4215 for (int i = 0; i < N; i++) {
4216 callbacks.get(i).onTrimMemory(level);
4219 WindowManagerGlobal.getInstance().trimMemory(level);
4222 private void setupGraphicsSupport(LoadedApk info, File cacheDir) {
4223 if (Process.isIsolated()) {
4224 // Isolated processes aren't going to do UI.
4228 int uid = Process.myUid();
4229 String[] packages = getPackageManager().getPackagesForUid(uid);
4231 // If there are several packages in this application we won't
4232 // initialize the graphics disk caches
4233 if (packages != null && packages.length == 1) {
4234 HardwareRenderer.setupDiskCache(cacheDir);
4235 RenderScript.setupDiskCache(cacheDir);
4237 } catch (RemoteException e) {
4242 private void updateDefaultDensity() {
4243 if (mCurDefaultDisplayDpi != Configuration.DENSITY_DPI_UNDEFINED
4244 && mCurDefaultDisplayDpi != DisplayMetrics.DENSITY_DEVICE
4245 && !mDensityCompatMode) {
4246 Slog.i(TAG, "Switching default density from "
4247 + DisplayMetrics.DENSITY_DEVICE + " to "
4248 + mCurDefaultDisplayDpi);
4249 DisplayMetrics.DENSITY_DEVICE = mCurDefaultDisplayDpi;
4250 Bitmap.setDefaultDensity(DisplayMetrics.DENSITY_DEFAULT);
4254 private void handleBindApplication(AppBindData data) {
4255 mBoundApplication = data;
4256 mConfiguration = new Configuration(data.config);
4257 mCompatConfiguration = new Configuration(data.config);
4259 mProfiler = new Profiler();
4260 if (data.initProfilerInfo != null) {
4261 mProfiler.profileFile = data.initProfilerInfo.profileFile;
4262 mProfiler.profileFd = data.initProfilerInfo.profileFd;
4263 mProfiler.samplingInterval = data.initProfilerInfo.samplingInterval;
4264 mProfiler.autoStopProfiler = data.initProfilerInfo.autoStopProfiler;
4267 // send up app name; do this *before* waiting for debugger
4268 Process.setArgV0(data.processName);
4269 android.ddm.DdmHandleAppName.setAppName(data.processName,
4270 UserHandle.myUserId());
4272 if (data.persistent) {
4273 // Persistent processes on low-memory devices do not get to
4274 // use hardware accelerated drawing, since this can add too much
4275 // overhead to the process.
4276 if (!ActivityManager.isHighEndGfx()) {
4277 HardwareRenderer.disable(false);
4281 if (mProfiler.profileFd != null) {
4282 mProfiler.startProfiling();
4285 // If the app is Honeycomb MR1 or earlier, switch its AsyncTask
4286 // implementation to use the pool executor. Normally, we use the
4287 // serialized executor as the default. This has to happen in the
4288 // main thread so the main looper is set right.
4289 if (data.appInfo.targetSdkVersion <= android.os.Build.VERSION_CODES.HONEYCOMB_MR1) {
4290 AsyncTask.setDefaultExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
4293 Message.updateCheckRecycle(data.appInfo.targetSdkVersion);
4296 * Before spawning a new process, reset the time zone to be the system time zone.
4297 * This needs to be done because the system time zone could have changed after the
4298 * the spawning of this process. Without doing this this process would have the incorrect
4301 TimeZone.setDefault(null);
4304 * Initialize the default locale in this process for the reasons we set the time zone.
4306 Locale.setDefault(data.config.locale);
4309 * Update the system configuration since its preloaded and might not
4310 * reflect configuration changes. The configuration object passed
4311 * in AppBindData can be safely assumed to be up to date
4313 mResourcesManager.applyConfigurationToResourcesLocked(data.config, data.compatInfo);
4314 mCurDefaultDisplayDpi = data.config.densityDpi;
4315 applyCompatConfiguration(mCurDefaultDisplayDpi);
4317 data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
4320 * Switch this process to density compatibility mode if needed.
4322 if ((data.appInfo.flags&ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES)
4324 mDensityCompatMode = true;
4325 Bitmap.setDefaultDensity(DisplayMetrics.DENSITY_DEFAULT);
4327 updateDefaultDensity();
4329 final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);
4330 if (!Process.isIsolated()) {
4331 final File cacheDir = appContext.getCacheDir();
4333 if (cacheDir != null) {
4334 // Provide a usable directory for temporary files
4335 System.setProperty("java.io.tmpdir", cacheDir.getAbsolutePath());
4337 setupGraphicsSupport(data.info, cacheDir);
4339 Log.e(TAG, "Unable to setupGraphicsSupport due to missing cache directory");
4344 final boolean is24Hr = "24".equals(mCoreSettings.getString(Settings.System.TIME_12_24));
4345 DateFormat.set24HourTimePref(is24Hr);
4347 View.mDebugViewAttributes =
4348 mCoreSettings.getInt(Settings.Global.DEBUG_VIEW_ATTRIBUTES, 0) != 0;
4351 * For system applications on userdebug/eng builds, log stack
4352 * traces of disk and network access to dropbox for analysis.
4354 if ((data.appInfo.flags &
4355 (ApplicationInfo.FLAG_SYSTEM |
4356 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0) {
4357 StrictMode.conditionallyEnableDebugLogging();
4361 * For apps targetting SDK Honeycomb or later, we don't allow
4362 * network usage on the main event loop / UI thread.
4364 * Note to those grepping: this is what ultimately throws
4365 * NetworkOnMainThreadException ...
4367 if (data.appInfo.targetSdkVersion > 9) {
4368 StrictMode.enableDeathOnNetwork();
4371 if (data.debugMode != IApplicationThread.DEBUG_OFF) {
4372 // XXX should have option to change the port.
4373 Debug.changeDebugPort(8100);
4374 if (data.debugMode == IApplicationThread.DEBUG_WAIT) {
4375 Slog.w(TAG, "Application " + data.info.getPackageName()
4376 + " is waiting for the debugger on port 8100...");
4378 IActivityManager mgr = ActivityManagerNative.getDefault();
4380 mgr.showWaitingForDebugger(mAppThread, true);
4381 } catch (RemoteException ex) {
4384 Debug.waitForDebugger();
4387 mgr.showWaitingForDebugger(mAppThread, false);
4388 } catch (RemoteException ex) {
4392 Slog.w(TAG, "Application " + data.info.getPackageName()
4393 + " can be debugged on port 8100...");
4397 // Enable OpenGL tracing if required
4398 if (data.enableOpenGlTrace) {
4399 GLUtils.setTracingLevel(1);
4402 // Allow application-generated systrace messages if we're debuggable.
4403 boolean appTracingAllowed = (data.appInfo.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0;
4404 Trace.setAppTracingAllowed(appTracingAllowed);
4407 * Initialize the default http proxy in this process for the reasons we set the time zone.
4409 IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE);
4411 // In pre-boot mode (doing initial launch to collect password), not
4412 // all system is up. This includes the connectivity service, so don't
4413 // crash if we can't get it.
4414 IConnectivityManager service = IConnectivityManager.Stub.asInterface(b);
4416 ProxyInfo proxyInfo = service.getProxy();
4417 Proxy.setHttpProxySystemProperty(proxyInfo);
4418 } catch (RemoteException e) {}
4421 if (data.instrumentationName != null) {
4422 InstrumentationInfo ii = null;
4424 ii = appContext.getPackageManager().
4425 getInstrumentationInfo(data.instrumentationName, 0);
4426 } catch (PackageManager.NameNotFoundException e) {
4429 throw new RuntimeException(
4430 "Unable to find instrumentation info for: "
4431 + data.instrumentationName);
4434 mInstrumentationPackageName = ii.packageName;
4435 mInstrumentationAppDir = ii.sourceDir;
4436 mInstrumentationSplitAppDirs = ii.splitSourceDirs;
4437 mInstrumentationLibDir = ii.nativeLibraryDir;
4438 mInstrumentedAppDir = data.info.getAppDir();
4439 mInstrumentedSplitAppDirs = data.info.getSplitAppDirs();
4440 mInstrumentedLibDir = data.info.getLibDir();
4442 ApplicationInfo instrApp = new ApplicationInfo();
4443 instrApp.packageName = ii.packageName;
4444 instrApp.sourceDir = ii.sourceDir;
4445 instrApp.publicSourceDir = ii.publicSourceDir;
4446 instrApp.splitSourceDirs = ii.splitSourceDirs;
4447 instrApp.splitPublicSourceDirs = ii.splitPublicSourceDirs;
4448 instrApp.dataDir = ii.dataDir;
4449 instrApp.nativeLibraryDir = ii.nativeLibraryDir;
4450 LoadedApk pi = getPackageInfo(instrApp, data.compatInfo,
4451 appContext.getClassLoader(), false, true, false);
4452 ContextImpl instrContext = ContextImpl.createAppContext(this, pi);
4455 java.lang.ClassLoader cl = instrContext.getClassLoader();
4456 mInstrumentation = (Instrumentation)
4457 cl.loadClass(data.instrumentationName.getClassName()).newInstance();
4458 } catch (Exception e) {
4459 throw new RuntimeException(
4460 "Unable to instantiate instrumentation "
4461 + data.instrumentationName + ": " + e.toString(), e);
4464 mInstrumentation.init(this, instrContext, appContext,
4465 new ComponentName(ii.packageName, ii.name), data.instrumentationWatcher,
4466 data.instrumentationUiAutomationConnection);
4468 if (mProfiler.profileFile != null && !ii.handleProfiling
4469 && mProfiler.profileFd == null) {
4470 mProfiler.handlingProfiling = true;
4471 File file = new File(mProfiler.profileFile);
4472 file.getParentFile().mkdirs();
4473 Debug.startMethodTracing(file.toString(), 8 * 1024 * 1024);
4477 mInstrumentation = new Instrumentation();
4480 if ((data.appInfo.flags&ApplicationInfo.FLAG_LARGE_HEAP) != 0) {
4481 dalvik.system.VMRuntime.getRuntime().clearGrowthLimit();
4484 // Allow disk access during application and provider setup. This could
4485 // block processing ordered broadcasts, but later processing would
4486 // probably end up doing the same disk access.
4487 final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskWrites();
4489 // If the app is being launched for full backup or restore, bring it up in
4490 // a restricted environment with the base application class.
4491 Application app = data.info.makeApplication(data.restrictedBackupMode, null);
4492 mInitialApplication = app;
4494 // don't bring up providers in restricted mode; they may depend on the
4495 // app's custom Application class
4496 if (!data.restrictedBackupMode) {
4497 List<ProviderInfo> providers = data.providers;
4498 if (providers != null) {
4499 installContentProviders(app, providers);
4500 // For process that contains content providers, we want to
4501 // ensure that the JIT is enabled "at some point".
4502 mH.sendEmptyMessageDelayed(H.ENABLE_JIT, 10*1000);
4506 // Do this after providers, since instrumentation tests generally start their
4507 // test thread at this point, and we don't want that racing.
4509 mInstrumentation.onCreate(data.instrumentationArgs);
4511 catch (Exception e) {
4512 throw new RuntimeException(
4513 "Exception thrown in onCreate() of "
4514 + data.instrumentationName + ": " + e.toString(), e);
4518 mInstrumentation.callApplicationOnCreate(app);
4519 } catch (Exception e) {
4520 if (!mInstrumentation.onException(app, e)) {
4521 throw new RuntimeException(
4522 "Unable to create application " + app.getClass().getName()
4523 + ": " + e.toString(), e);
4527 StrictMode.setThreadPolicy(savedPolicy);
4531 /*package*/ final void finishInstrumentation(int resultCode, Bundle results) {
4532 IActivityManager am = ActivityManagerNative.getDefault();
4533 if (mProfiler.profileFile != null && mProfiler.handlingProfiling
4534 && mProfiler.profileFd == null) {
4535 Debug.stopMethodTracing();
4537 //Slog.i(TAG, "am: " + ActivityManagerNative.getDefault()
4538 // + ", app thr: " + mAppThread);
4540 am.finishInstrumentation(mAppThread, resultCode, results);
4541 } catch (RemoteException ex) {
4545 private void installContentProviders(
4546 Context context, List<ProviderInfo> providers) {
4547 final ArrayList<IActivityManager.ContentProviderHolder> results =
4548 new ArrayList<IActivityManager.ContentProviderHolder>();
4550 for (ProviderInfo cpi : providers) {
4551 if (DEBUG_PROVIDER) {
4552 StringBuilder buf = new StringBuilder(128);
4554 buf.append(cpi.authority);
4556 buf.append(cpi.name);
4557 Log.i(TAG, buf.toString());
4559 IActivityManager.ContentProviderHolder cph = installProvider(context, null, cpi,
4560 false /*noisy*/, true /*noReleaseNeeded*/, true /*stable*/);
4562 cph.noReleaseNeeded = true;
4568 ActivityManagerNative.getDefault().publishContentProviders(
4569 getApplicationThread(), results);
4570 } catch (RemoteException ex) {
4574 public final IContentProvider acquireProvider(
4575 Context c, String auth, int userId, boolean stable) {
4576 final IContentProvider provider = acquireExistingProvider(c, auth, userId, stable);
4577 if (provider != null) {
4581 // There is a possible race here. Another thread may try to acquire
4582 // the same provider at the same time. When this happens, we want to ensure
4583 // that the first one wins.
4584 // Note that we cannot hold the lock while acquiring and installing the
4585 // provider since it might take a long time to run and it could also potentially
4586 // be re-entrant in the case where the provider is in the same process.
4587 IActivityManager.ContentProviderHolder holder = null;
4589 holder = ActivityManagerNative.getDefault().getContentProvider(
4590 getApplicationThread(), auth, userId, stable);
4591 } catch (RemoteException ex) {
4593 if (holder == null) {
4594 Slog.e(TAG, "Failed to find provider info for " + auth);
4598 // Install provider will increment the reference count for us, and break
4599 // any ties in the race.
4600 holder = installProvider(c, holder, holder.info,
4601 true /*noisy*/, holder.noReleaseNeeded, stable);
4602 return holder.provider;
4605 private final void incProviderRefLocked(ProviderRefCount prc, boolean stable) {
4607 prc.stableCount += 1;
4608 if (prc.stableCount == 1) {
4609 // We are acquiring a new stable reference on the provider.
4611 if (prc.removePending) {
4612 // We have a pending remove operation, which is holding the
4613 // last unstable reference. At this point we are converting
4614 // that unstable reference to our new stable reference.
4616 // Cancel the removal of the provider.
4617 if (DEBUG_PROVIDER) {
4618 Slog.v(TAG, "incProviderRef: stable "
4619 + "snatched provider from the jaws of death");
4621 prc.removePending = false;
4622 // There is a race! It fails to remove the message, which
4623 // will be handled in completeRemoveProvider().
4624 mH.removeMessages(H.REMOVE_PROVIDER, prc);
4629 if (DEBUG_PROVIDER) {
4630 Slog.v(TAG, "incProviderRef Now stable - "
4631 + prc.holder.info.name + ": unstableDelta="
4634 ActivityManagerNative.getDefault().refContentProvider(
4635 prc.holder.connection, 1, unstableDelta);
4636 } catch (RemoteException e) {
4637 //do nothing content provider object is dead any way
4641 prc.unstableCount += 1;
4642 if (prc.unstableCount == 1) {
4643 // We are acquiring a new unstable reference on the provider.
4644 if (prc.removePending) {
4645 // Oh look, we actually have a remove pending for the
4646 // provider, which is still holding the last unstable
4647 // reference. We just need to cancel that to take new
4648 // ownership of the reference.
4649 if (DEBUG_PROVIDER) {
4650 Slog.v(TAG, "incProviderRef: unstable "
4651 + "snatched provider from the jaws of death");
4653 prc.removePending = false;
4654 mH.removeMessages(H.REMOVE_PROVIDER, prc);
4656 // First unstable ref, increment our count in the
4657 // activity manager.
4659 if (DEBUG_PROVIDER) {
4660 Slog.v(TAG, "incProviderRef: Now unstable - "
4661 + prc.holder.info.name);
4663 ActivityManagerNative.getDefault().refContentProvider(
4664 prc.holder.connection, 0, 1);
4665 } catch (RemoteException e) {
4666 //do nothing content provider object is dead any way
4673 public final IContentProvider acquireExistingProvider(
4674 Context c, String auth, int userId, boolean stable) {
4675 synchronized (mProviderMap) {
4676 final ProviderKey key = new ProviderKey(auth, userId);
4677 final ProviderClientRecord pr = mProviderMap.get(key);
4682 IContentProvider provider = pr.mProvider;
4683 IBinder jBinder = provider.asBinder();
4684 if (!jBinder.isBinderAlive()) {
4685 // The hosting process of the provider has died; we can't
4687 Log.i(TAG, "Acquiring provider " + auth + " for user " + userId
4688 + ": existing object's process dead");
4689 handleUnstableProviderDiedLocked(jBinder, true);
4693 // Only increment the ref count if we have one. If we don't then the
4694 // provider is not reference counted and never needs to be released.
4695 ProviderRefCount prc = mProviderRefCountMap.get(jBinder);
4697 incProviderRefLocked(prc, stable);
4703 public final boolean releaseProvider(IContentProvider provider, boolean stable) {
4704 if (provider == null) {
4708 IBinder jBinder = provider.asBinder();
4709 synchronized (mProviderMap) {
4710 ProviderRefCount prc = mProviderRefCountMap.get(jBinder);
4712 // The provider has no ref count, no release is needed.
4716 boolean lastRef = false;
4718 if (prc.stableCount == 0) {
4719 if (DEBUG_PROVIDER) Slog.v(TAG,
4720 "releaseProvider: stable ref count already 0, how?");
4723 prc.stableCount -= 1;
4724 if (prc.stableCount == 0) {
4725 // What we do at this point depends on whether there are
4726 // any unstable refs left: if there are, we just tell the
4727 // activity manager to decrement its stable count; if there
4728 // aren't, we need to enqueue this provider to be removed,
4729 // and convert to holding a single unstable ref while
4731 lastRef = prc.unstableCount == 0;
4733 if (DEBUG_PROVIDER) {
4734 Slog.v(TAG, "releaseProvider: No longer stable w/lastRef="
4735 + lastRef + " - " + prc.holder.info.name);
4737 ActivityManagerNative.getDefault().refContentProvider(
4738 prc.holder.connection, -1, lastRef ? 1 : 0);
4739 } catch (RemoteException e) {
4740 //do nothing content provider object is dead any way
4744 if (prc.unstableCount == 0) {
4745 if (DEBUG_PROVIDER) Slog.v(TAG,
4746 "releaseProvider: unstable ref count already 0, how?");
4749 prc.unstableCount -= 1;
4750 if (prc.unstableCount == 0) {
4751 // If this is the last reference, we need to enqueue
4752 // this provider to be removed instead of telling the
4753 // activity manager to remove it at this point.
4754 lastRef = prc.stableCount == 0;
4757 if (DEBUG_PROVIDER) {
4758 Slog.v(TAG, "releaseProvider: No longer unstable - "
4759 + prc.holder.info.name);
4761 ActivityManagerNative.getDefault().refContentProvider(
4762 prc.holder.connection, 0, -1);
4763 } catch (RemoteException e) {
4764 //do nothing content provider object is dead any way
4771 if (!prc.removePending) {
4772 // Schedule the actual remove asynchronously, since we don't know the context
4773 // this will be called in.
4774 // TODO: it would be nice to post a delayed message, so
4775 // if we come back and need the same provider quickly
4776 // we will still have it available.
4777 if (DEBUG_PROVIDER) {
4778 Slog.v(TAG, "releaseProvider: Enqueueing pending removal - "
4779 + prc.holder.info.name);
4781 prc.removePending = true;
4782 Message msg = mH.obtainMessage(H.REMOVE_PROVIDER, prc);
4783 mH.sendMessage(msg);
4785 Slog.w(TAG, "Duplicate remove pending of provider " + prc.holder.info.name);
4792 final void completeRemoveProvider(ProviderRefCount prc) {
4793 synchronized (mProviderMap) {
4794 if (!prc.removePending) {
4795 // There was a race! Some other client managed to acquire
4796 // the provider before the removal was completed.
4797 // Abort the removal. We will do it later.
4798 if (DEBUG_PROVIDER) Slog.v(TAG, "completeRemoveProvider: lost the race, "
4799 + "provider still in use");
4803 // More complicated race!! Some client managed to acquire the
4804 // provider and release it before the removal was completed.
4805 // Continue the removal, and abort the next remove message.
4806 prc.removePending = false;
4808 final IBinder jBinder = prc.holder.provider.asBinder();
4809 ProviderRefCount existingPrc = mProviderRefCountMap.get(jBinder);
4810 if (existingPrc == prc) {
4811 mProviderRefCountMap.remove(jBinder);
4814 for (int i=mProviderMap.size()-1; i>=0; i--) {
4815 ProviderClientRecord pr = mProviderMap.valueAt(i);
4816 IBinder myBinder = pr.mProvider.asBinder();
4817 if (myBinder == jBinder) {
4818 mProviderMap.removeAt(i);
4824 if (DEBUG_PROVIDER) {
4825 Slog.v(TAG, "removeProvider: Invoking ActivityManagerNative."
4826 + "removeContentProvider(" + prc.holder.info.name + ")");
4828 ActivityManagerNative.getDefault().removeContentProvider(
4829 prc.holder.connection, false);
4830 } catch (RemoteException e) {
4831 //do nothing content provider object is dead any way
4835 final void handleUnstableProviderDied(IBinder provider, boolean fromClient) {
4836 synchronized (mProviderMap) {
4837 handleUnstableProviderDiedLocked(provider, fromClient);
4841 final void handleUnstableProviderDiedLocked(IBinder provider, boolean fromClient) {
4842 ProviderRefCount prc = mProviderRefCountMap.get(provider);
4844 if (DEBUG_PROVIDER) Slog.v(TAG, "Cleaning up dead provider "
4845 + provider + " " + prc.holder.info.name);
4846 mProviderRefCountMap.remove(provider);
4847 for (int i=mProviderMap.size()-1; i>=0; i--) {
4848 ProviderClientRecord pr = mProviderMap.valueAt(i);
4849 if (pr != null && pr.mProvider.asBinder() == provider) {
4850 Slog.i(TAG, "Removing dead content provider:" + pr.mProvider.toString());
4851 mProviderMap.removeAt(i);
4856 // We found out about this due to execution in our client
4857 // code. Tell the activity manager about it now, to ensure
4858 // that the next time we go to do anything with the provider
4859 // it knows it is dead (so we don't race with its death
4862 ActivityManagerNative.getDefault().unstableProviderDied(
4863 prc.holder.connection);
4864 } catch (RemoteException e) {
4865 //do nothing content provider object is dead any way
4871 final void appNotRespondingViaProvider(IBinder provider) {
4872 synchronized (mProviderMap) {
4873 ProviderRefCount prc = mProviderRefCountMap.get(provider);
4876 ActivityManagerNative.getDefault()
4877 .appNotRespondingViaProvider(prc.holder.connection);
4878 } catch (RemoteException e) {
4884 private ProviderClientRecord installProviderAuthoritiesLocked(IContentProvider provider,
4885 ContentProvider localProvider, IActivityManager.ContentProviderHolder holder) {
4886 final String auths[] = PATTERN_SEMICOLON.split(holder.info.authority);
4887 final int userId = UserHandle.getUserId(holder.info.applicationInfo.uid);
4889 final ProviderClientRecord pcr = new ProviderClientRecord(
4890 auths, provider, localProvider, holder);
4891 for (String auth : auths) {
4892 final ProviderKey key = new ProviderKey(auth, userId);
4893 final ProviderClientRecord existing = mProviderMap.get(key);
4894 if (existing != null) {
4895 Slog.w(TAG, "Content provider " + pcr.mHolder.info.name
4896 + " already published as " + auth);
4898 mProviderMap.put(key, pcr);
4905 * Installs the provider.
4907 * Providers that are local to the process or that come from the system server
4908 * may be installed permanently which is indicated by setting noReleaseNeeded to true.
4909 * Other remote providers are reference counted. The initial reference count
4910 * for all reference counted providers is one. Providers that are not reference
4911 * counted do not have a reference count (at all).
4913 * This method detects when a provider has already been installed. When this happens,
4914 * it increments the reference count of the existing provider (if appropriate)
4915 * and returns the existing provider. This can happen due to concurrent
4916 * attempts to acquire the same provider.
4918 private IActivityManager.ContentProviderHolder installProvider(Context context,
4919 IActivityManager.ContentProviderHolder holder, ProviderInfo info,
4920 boolean noisy, boolean noReleaseNeeded, boolean stable) {
4921 ContentProvider localProvider = null;
4922 IContentProvider provider;
4923 if (holder == null || holder.provider == null) {
4924 if (DEBUG_PROVIDER || noisy) {
4925 Slog.d(TAG, "Loading provider " + info.authority + ": "
4929 ApplicationInfo ai = info.applicationInfo;
4930 if (context.getPackageName().equals(ai.packageName)) {
4932 } else if (mInitialApplication != null &&
4933 mInitialApplication.getPackageName().equals(ai.packageName)) {
4934 c = mInitialApplication;
4937 c = context.createPackageContext(ai.packageName,
4938 Context.CONTEXT_INCLUDE_CODE);
4939 } catch (PackageManager.NameNotFoundException e) {
4944 Slog.w(TAG, "Unable to get context for package " +
4946 " while loading content provider " +
4951 final java.lang.ClassLoader cl = c.getClassLoader();
4952 localProvider = (ContentProvider)cl.
4953 loadClass(info.name).newInstance();
4954 provider = localProvider.getIContentProvider();
4955 if (provider == null) {
4956 Slog.e(TAG, "Failed to instantiate class " +
4957 info.name + " from sourceDir " +
4958 info.applicationInfo.sourceDir);
4961 if (DEBUG_PROVIDER) Slog.v(
4962 TAG, "Instantiating local provider " + info.name);
4963 // XXX Need to create the correct context for this provider.
4964 localProvider.attachInfo(c, info);
4965 } catch (java.lang.Exception e) {
4966 if (!mInstrumentation.onException(null, e)) {
4967 throw new RuntimeException(
4968 "Unable to get provider " + info.name
4969 + ": " + e.toString(), e);
4974 provider = holder.provider;
4975 if (DEBUG_PROVIDER) Slog.v(TAG, "Installing external provider " + info.authority + ": "
4979 IActivityManager.ContentProviderHolder retHolder;
4981 synchronized (mProviderMap) {
4982 if (DEBUG_PROVIDER) Slog.v(TAG, "Checking to add " + provider
4983 + " / " + info.name);
4984 IBinder jBinder = provider.asBinder();
4985 if (localProvider != null) {
4986 ComponentName cname = new ComponentName(info.packageName, info.name);
4987 ProviderClientRecord pr = mLocalProvidersByName.get(cname);
4989 if (DEBUG_PROVIDER) {
4990 Slog.v(TAG, "installProvider: lost the race, "
4991 + "using existing local provider");
4993 provider = pr.mProvider;
4995 holder = new IActivityManager.ContentProviderHolder(info);
4996 holder.provider = provider;
4997 holder.noReleaseNeeded = true;
4998 pr = installProviderAuthoritiesLocked(provider, localProvider, holder);
4999 mLocalProviders.put(jBinder, pr);
5000 mLocalProvidersByName.put(cname, pr);
5002 retHolder = pr.mHolder;
5004 ProviderRefCount prc = mProviderRefCountMap.get(jBinder);
5006 if (DEBUG_PROVIDER) {
5007 Slog.v(TAG, "installProvider: lost the race, updating ref count");
5009 // We need to transfer our new reference to the existing
5010 // ref count, releasing the old one... but only if
5011 // release is needed (that is, it is not running in the
5013 if (!noReleaseNeeded) {
5014 incProviderRefLocked(prc, stable);
5016 ActivityManagerNative.getDefault().removeContentProvider(
5017 holder.connection, stable);
5018 } catch (RemoteException e) {
5019 //do nothing content provider object is dead any way
5023 ProviderClientRecord client = installProviderAuthoritiesLocked(
5024 provider, localProvider, holder);
5025 if (noReleaseNeeded) {
5026 prc = new ProviderRefCount(holder, client, 1000, 1000);
5029 ? new ProviderRefCount(holder, client, 1, 0)
5030 : new ProviderRefCount(holder, client, 0, 1);
5032 mProviderRefCountMap.put(jBinder, prc);
5034 retHolder = prc.holder;
5041 private void attach(boolean system) {
5042 sCurrentActivityThread = this;
5043 mSystemThread = system;
5045 ViewRootImpl.addFirstDrawHandler(new Runnable() {
5051 android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",
5052 UserHandle.myUserId());
5053 RuntimeInit.setApplicationObject(mAppThread.asBinder());
5054 final IActivityManager mgr = ActivityManagerNative.getDefault();
5056 mgr.attachApplication(mAppThread);
5057 } catch (RemoteException ex) {
5060 // Watch for getting close to heap limit.
5061 BinderInternal.addGcWatcher(new Runnable() {
5062 @Override public void run() {
5063 if (!mSomeActivitiesChanged) {
5066 Runtime runtime = Runtime.getRuntime();
5067 long dalvikMax = runtime.maxMemory();
5068 long dalvikUsed = runtime.totalMemory() - runtime.freeMemory();
5069 if (dalvikUsed > ((3*dalvikMax)/4)) {
5070 if (DEBUG_MEMORY_TRIM) Slog.d(TAG, "Dalvik max=" + (dalvikMax/1024)
5071 + " total=" + (runtime.totalMemory()/1024)
5072 + " used=" + (dalvikUsed/1024));
5073 mSomeActivitiesChanged = false;
5075 mgr.releaseSomeActivities(mAppThread);
5076 } catch (RemoteException e) {
5082 // Don't set application object here -- if the system crashes,
5083 // we can't display an alert, we just want to die die die.
5084 android.ddm.DdmHandleAppName.setAppName("system_process",
5085 UserHandle.myUserId());
5087 mInstrumentation = new Instrumentation();
5088 ContextImpl context = ContextImpl.createAppContext(
5089 this, getSystemContext().mPackageInfo);
5090 mInitialApplication = context.mPackageInfo.makeApplication(true, null);
5091 mInitialApplication.onCreate();
5092 } catch (Exception e) {
5093 throw new RuntimeException(
5094 "Unable to instantiate Application():" + e.toString(), e);
5098 // add dropbox logging to libcore
5099 DropBox.setReporter(new DropBoxReporter());
5101 ViewRootImpl.addConfigCallback(new ComponentCallbacks2() {
5103 public void onConfigurationChanged(Configuration newConfig) {
5104 synchronized (mResourcesManager) {
5105 // We need to apply this change to the resources
5106 // immediately, because upon returning the view
5107 // hierarchy will be informed about it.
5108 if (mResourcesManager.applyConfigurationToResourcesLocked(newConfig, null)) {
5109 // This actually changed the resources! Tell
5110 // everyone about it.
5111 if (mPendingConfiguration == null ||
5112 mPendingConfiguration.isOtherSeqNewer(newConfig)) {
5113 mPendingConfiguration = newConfig;
5115 sendMessage(H.CONFIGURATION_CHANGED, newConfig);
5121 public void onLowMemory() {
5124 public void onTrimMemory(int level) {
5129 public static ActivityThread systemMain() {
5130 // The system process on low-memory devices do not get to use hardware
5131 // accelerated drawing, since this can add too much overhead to the
5133 if (!ActivityManager.isHighEndGfx()) {
5134 HardwareRenderer.disable(true);
5136 HardwareRenderer.enableForegroundTrimming();
5138 ActivityThread thread = new ActivityThread();
5139 thread.attach(true);
5143 public final void installSystemProviders(List<ProviderInfo> providers) {
5144 if (providers != null) {
5145 installContentProviders(mInitialApplication, providers);
5149 public int getIntCoreSetting(String key, int defaultValue) {
5150 synchronized (mResourcesManager) {
5151 if (mCoreSettings != null) {
5152 return mCoreSettings.getInt(key, defaultValue);
5154 return defaultValue;
5158 private static class EventLoggingReporter implements EventLogger.Reporter {
5160 public void report (int code, Object... list) {
5161 EventLog.writeEvent(code, list);
5165 private class DropBoxReporter implements DropBox.Reporter {
5167 private DropBoxManager dropBox;
5169 public DropBoxReporter() {
5170 dropBox = (DropBoxManager) getSystemContext().getSystemService(Context.DROPBOX_SERVICE);
5174 public void addData(String tag, byte[] data, int flags) {
5175 dropBox.addData(tag, data, flags);
5179 public void addText(String tag, String data) {
5180 dropBox.addText(tag, data);
5184 public static void main(String[] args) {
5185 SamplingProfilerIntegration.start();
5187 // CloseGuard defaults to true and can be quite spammy. We
5188 // disable it here, but selectively enable it later (via
5189 // StrictMode) on debug builds, but using DropBox, not logs.
5190 CloseGuard.setEnabled(false);
5192 Environment.initForCurrentUser();
5194 // Set the reporter for event logging in libcore
5195 EventLogger.setReporter(new EventLoggingReporter());
5197 Security.addProvider(new AndroidKeyStoreProvider());
5199 // Make sure TrustedCertificateStore looks in the right place for CA certificates
5200 final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
5201 TrustedCertificateStore.setDefaultUserDirectory(configDir);
5203 Process.setArgV0("<pre-initialized>");
5205 Looper.prepareMainLooper();
5207 ActivityThread thread = new ActivityThread();
5208 thread.attach(false);
5210 if (sMainThreadHandler == null) {
5211 sMainThreadHandler = thread.getHandler();
5217 Looper.myLooper().setMessageLogging(new
5218 LogPrinter(Log.DEBUG, "ActivityThread"));
5223 throw new RuntimeException("Main thread loop unexpectedly exited");