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.ConnectivityManager;
48 import android.net.IConnectivityManager;
49 import android.net.LinkProperties;
50 import android.net.Network;
51 import android.net.Proxy;
52 import android.net.ProxyInfo;
53 import android.net.Uri;
54 import android.opengl.GLUtils;
55 import android.os.AsyncTask;
56 import android.os.Binder;
57 import android.os.Bundle;
58 import android.os.Debug;
59 import android.os.DropBoxManager;
60 import android.os.Environment;
61 import android.os.Handler;
62 import android.os.IBinder;
63 import android.os.Looper;
64 import android.os.Message;
65 import android.os.MessageQueue;
66 import android.os.Parcel;
67 import android.os.ParcelFileDescriptor;
68 import android.os.PersistableBundle;
69 import android.os.Process;
70 import android.os.RemoteException;
71 import android.os.ServiceManager;
72 import android.os.StrictMode;
73 import android.os.SystemClock;
74 import android.os.SystemProperties;
75 import android.os.Trace;
76 import android.os.UserHandle;
77 import android.provider.Settings;
78 import android.util.AndroidRuntimeException;
79 import android.util.ArrayMap;
80 import android.util.DisplayMetrics;
81 import android.util.EventLog;
82 import android.util.Log;
83 import android.util.LogPrinter;
84 import android.util.Pair;
85 import android.util.PrintWriterPrinter;
86 import android.util.Slog;
87 import android.util.SuperNotCalledException;
88 import android.view.Display;
89 import android.view.HardwareRenderer;
90 import android.view.IWindowManager;
91 import android.view.IWindowSessionCallback;
92 import android.view.View;
93 import android.view.ViewDebug;
94 import android.view.ViewManager;
95 import android.view.ViewRootImpl;
96 import android.view.Window;
97 import android.view.WindowManager;
98 import android.view.WindowManagerGlobal;
99 import android.renderscript.RenderScript;
100 import android.security.AndroidKeyStoreProvider;
102 import com.android.internal.app.IVoiceInteractor;
103 import com.android.internal.content.ReferrerIntent;
104 import com.android.internal.os.BinderInternal;
105 import com.android.internal.os.RuntimeInit;
106 import com.android.internal.os.SamplingProfilerIntegration;
107 import com.android.internal.util.FastPrintWriter;
108 import com.android.org.conscrypt.OpenSSLSocketImpl;
109 import com.android.org.conscrypt.TrustedCertificateStore;
110 import com.google.android.collect.Lists;
113 import java.io.FileDescriptor;
114 import java.io.FileOutputStream;
115 import java.io.IOException;
116 import java.io.PrintWriter;
117 import java.lang.ref.WeakReference;
118 import java.net.InetAddress;
119 import java.security.Security;
120 import java.text.DateFormat;
121 import java.util.ArrayList;
122 import java.util.List;
123 import java.util.Locale;
124 import java.util.Map;
125 import java.util.Objects;
126 import java.util.TimeZone;
127 import java.util.regex.Pattern;
129 import libcore.io.DropBox;
130 import libcore.io.EventLogger;
131 import libcore.io.IoUtils;
132 import libcore.net.event.NetworkEventDispatcher;
133 import dalvik.system.CloseGuard;
134 import dalvik.system.VMDebug;
135 import dalvik.system.VMRuntime;
137 final class RemoteServiceException extends AndroidRuntimeException {
138 public RemoteServiceException(String msg) {
144 * This manages the execution of the main thread in an
145 * application process, scheduling and executing activities,
146 * broadcasts, and other operations on it as the activity
151 public final class ActivityThread {
153 public static final String TAG = "ActivityThread";
154 private static final android.graphics.Bitmap.Config THUMBNAIL_FORMAT = Bitmap.Config.RGB_565;
155 static final boolean localLOGV = false;
156 static final boolean DEBUG_MESSAGES = false;
158 public static final boolean DEBUG_BROADCAST = false;
159 private static final boolean DEBUG_RESULTS = false;
160 private static final boolean DEBUG_BACKUP = false;
161 public static final boolean DEBUG_CONFIGURATION = false;
162 private static final boolean DEBUG_SERVICE = false;
163 private static final boolean DEBUG_MEMORY_TRIM = false;
164 private static final boolean DEBUG_PROVIDER = false;
165 private static final long MIN_TIME_BETWEEN_GCS = 5*1000;
166 private static final Pattern PATTERN_SEMICOLON = Pattern.compile(";");
167 private static final int SQLITE_MEM_RELEASED_EVENT_LOG_TAG = 75003;
168 private static final int LOG_ON_PAUSE_CALLED = 30021;
169 private static final int LOG_ON_RESUME_CALLED = 30022;
171 /** Type for IActivityManager.serviceDoneExecuting: anonymous operation */
172 public static final int SERVICE_DONE_EXECUTING_ANON = 0;
173 /** Type for IActivityManager.serviceDoneExecuting: done with an onStart call */
174 public static final int SERVICE_DONE_EXECUTING_START = 1;
175 /** Type for IActivityManager.serviceDoneExecuting: done stopping (destroying) service */
176 public static final int SERVICE_DONE_EXECUTING_STOP = 2;
178 private ContextImpl mSystemContext;
180 static IPackageManager sPackageManager;
182 final ApplicationThread mAppThread = new ApplicationThread();
183 final Looper mLooper = Looper.myLooper();
184 final H mH = new H();
185 final ArrayMap<IBinder, ActivityClientRecord> mActivities
186 = new ArrayMap<IBinder, ActivityClientRecord>();
187 // List of new activities (via ActivityRecord.nextIdle) that should
188 // be reported when next we idle.
189 ActivityClientRecord mNewActivities = null;
190 // Number of activities that are currently visible on-screen.
191 int mNumVisibleActivities = 0;
192 final ArrayMap<IBinder, Service> mServices
193 = new ArrayMap<IBinder, Service>();
194 AppBindData mBoundApplication;
196 int mCurDefaultDisplayDpi;
197 boolean mDensityCompatMode;
198 Configuration mConfiguration;
199 Configuration mCompatConfiguration;
200 Application mInitialApplication;
201 final ArrayList<Application> mAllApplications
202 = new ArrayList<Application>();
203 // set of instantiated backup agents, keyed by package name
204 final ArrayMap<String, BackupAgent> mBackupAgents = new ArrayMap<String, BackupAgent>();
205 /** Reference to singleton {@link ActivityThread} */
206 private static ActivityThread sCurrentActivityThread;
207 Instrumentation mInstrumentation;
208 String mInstrumentationPackageName = null;
209 String mInstrumentationAppDir = null;
210 String[] mInstrumentationSplitAppDirs = null;
211 String mInstrumentationLibDir = null;
212 String mInstrumentedAppDir = null;
213 String[] mInstrumentedSplitAppDirs = null;
214 String mInstrumentedLibDir = null;
215 boolean mSystemThread = false;
216 boolean mJitEnabled = false;
217 boolean mSomeActivitiesChanged = false;
219 // These can be accessed by multiple threads; mPackages is the lock.
220 // XXX For now we keep around information about all packages we have
221 // seen, not removing entries from this map.
222 // NOTE: The activity and window managers need to call in to
223 // ActivityThread to do things like update resource configurations,
224 // which means this lock gets held while the activity and window managers
225 // holds their own lock. Thus you MUST NEVER call back into the activity manager
226 // or window manager or anything that depends on them while holding this lock.
227 final ArrayMap<String, WeakReference<LoadedApk>> mPackages
228 = new ArrayMap<String, WeakReference<LoadedApk>>();
229 final ArrayMap<String, WeakReference<LoadedApk>> mResourcePackages
230 = new ArrayMap<String, WeakReference<LoadedApk>>();
231 final ArrayList<ActivityClientRecord> mRelaunchingActivities
232 = new ArrayList<ActivityClientRecord>();
233 Configuration mPendingConfiguration = null;
235 private final ResourcesManager mResourcesManager;
237 private static final class ProviderKey {
238 final String authority;
241 public ProviderKey(String authority, int userId) {
242 this.authority = authority;
243 this.userId = userId;
247 public boolean equals(Object o) {
248 if (o instanceof ProviderKey) {
249 final ProviderKey other = (ProviderKey) o;
250 return Objects.equals(authority, other.authority) && userId == other.userId;
256 public int hashCode() {
257 return ((authority != null) ? authority.hashCode() : 0) ^ userId;
261 // The lock of mProviderMap protects the following variables.
262 final ArrayMap<ProviderKey, ProviderClientRecord> mProviderMap
263 = new ArrayMap<ProviderKey, ProviderClientRecord>();
264 final ArrayMap<IBinder, ProviderRefCount> mProviderRefCountMap
265 = new ArrayMap<IBinder, ProviderRefCount>();
266 final ArrayMap<IBinder, ProviderClientRecord> mLocalProviders
267 = new ArrayMap<IBinder, ProviderClientRecord>();
268 final ArrayMap<ComponentName, ProviderClientRecord> mLocalProvidersByName
269 = new ArrayMap<ComponentName, ProviderClientRecord>();
271 final ArrayMap<Activity, ArrayList<OnActivityPausedListener>> mOnPauseListeners
272 = new ArrayMap<Activity, ArrayList<OnActivityPausedListener>>();
274 final GcIdler mGcIdler = new GcIdler();
275 boolean mGcIdlerScheduled = false;
277 static Handler sMainThreadHandler; // set once in main()
279 Bundle mCoreSettings = null;
281 static final class ActivityClientRecord {
286 IVoiceInteractor voiceInteractor;
288 PersistableBundle persistentState;
293 Activity.NonConfigurationInstances lastNonConfigurationInstances;
297 Configuration newConfig;
298 Configuration createdConfig;
299 ActivityClientRecord nextIdle;
301 ProfilerInfo profilerInfo;
303 ActivityInfo activityInfo;
304 CompatibilityInfo compatInfo;
305 LoadedApk packageInfo;
307 List<ResultInfo> pendingResults;
308 List<ReferrerIntent> pendingIntents;
310 boolean startsNotResumed;
312 int pendingConfigChanges;
313 boolean onlyLocalRequest;
315 View mPendingRemoveWindow;
316 WindowManager mPendingRemoveWindowManager;
318 ActivityClientRecord() {
327 public boolean isPreHoneycomb() {
328 if (activity != null) {
329 return activity.getApplicationInfo().targetSdkVersion
330 < android.os.Build.VERSION_CODES.HONEYCOMB;
335 public boolean isPersistable() {
336 return activityInfo.persistableMode == ActivityInfo.PERSIST_ACROSS_REBOOTS;
339 public String toString() {
340 ComponentName componentName = intent != null ? intent.getComponent() : null;
341 return "ActivityRecord{"
342 + Integer.toHexString(System.identityHashCode(this))
343 + " token=" + token + " " + (componentName == null
344 ? "no component name" : componentName.toShortString())
349 final class ProviderClientRecord {
350 final String[] mNames;
351 final IContentProvider mProvider;
352 final ContentProvider mLocalProvider;
353 final IActivityManager.ContentProviderHolder mHolder;
355 ProviderClientRecord(String[] names, IContentProvider provider,
356 ContentProvider localProvider,
357 IActivityManager.ContentProviderHolder holder) {
359 mProvider = provider;
360 mLocalProvider = localProvider;
365 static final class NewIntentData {
366 List<ReferrerIntent> intents;
368 public String toString() {
369 return "NewIntentData{intents=" + intents + " token=" + token + "}";
373 static final class ReceiverData extends BroadcastReceiver.PendingResult {
374 public ReceiverData(Intent intent, int resultCode, String resultData, Bundle resultExtras,
375 boolean ordered, boolean sticky, IBinder token, int sendingUser) {
376 super(resultCode, resultData, resultExtras, TYPE_COMPONENT, ordered, sticky,
378 this.intent = intent;
383 CompatibilityInfo compatInfo;
384 public String toString() {
385 return "ReceiverData{intent=" + intent + " packageName=" +
386 info.packageName + " resultCode=" + getResultCode()
387 + " resultData=" + getResultData() + " resultExtras="
388 + getResultExtras(false) + "}";
392 static final class CreateBackupAgentData {
393 ApplicationInfo appInfo;
394 CompatibilityInfo compatInfo;
396 public String toString() {
397 return "CreateBackupAgentData{appInfo=" + appInfo
398 + " backupAgent=" + appInfo.backupAgentName
399 + " mode=" + backupMode + "}";
403 static final class CreateServiceData {
406 CompatibilityInfo compatInfo;
408 public String toString() {
409 return "CreateServiceData{token=" + token + " className="
410 + info.name + " packageName=" + info.packageName
411 + " intent=" + intent + "}";
415 static final class BindServiceData {
419 public String toString() {
420 return "BindServiceData{token=" + token + " intent=" + intent + "}";
424 static final class ServiceArgsData {
430 public String toString() {
431 return "ServiceArgsData{token=" + token + " startId=" + startId
432 + " args=" + args + "}";
436 static final class AppBindData {
439 ApplicationInfo appInfo;
440 List<ProviderInfo> providers;
441 ComponentName instrumentationName;
442 Bundle instrumentationArgs;
443 IInstrumentationWatcher instrumentationWatcher;
444 IUiAutomationConnection instrumentationUiAutomationConnection;
446 boolean enableOpenGlTrace;
447 boolean restrictedBackupMode;
449 Configuration config;
450 CompatibilityInfo compatInfo;
452 /** Initial values for {@link Profiler}. */
453 ProfilerInfo initProfilerInfo;
455 public String toString() {
456 return "AppBindData{appInfo=" + appInfo + "}";
460 static final class Profiler {
462 ParcelFileDescriptor profileFd;
463 int samplingInterval;
464 boolean autoStopProfiler;
466 boolean handlingProfiling;
467 public void setProfiler(ProfilerInfo profilerInfo) {
468 ParcelFileDescriptor fd = profilerInfo.profileFd;
473 } catch (IOException e) {
479 if (profileFd != null) {
482 } catch (IOException e) {
486 profileFile = profilerInfo.profileFile;
488 samplingInterval = profilerInfo.samplingInterval;
489 autoStopProfiler = profilerInfo.autoStopProfiler;
491 public void startProfiling() {
492 if (profileFd == null || profiling) {
496 VMDebug.startMethodTracing(profileFile, profileFd.getFileDescriptor(),
497 8 * 1024 * 1024, 0, samplingInterval != 0, samplingInterval);
499 } catch (RuntimeException e) {
500 Slog.w(TAG, "Profiling failed on path " + profileFile);
504 } catch (IOException e2) {
505 Slog.w(TAG, "Failure closing profile fd", e2);
509 public void stopProfiling() {
512 Debug.stopMethodTracing();
513 if (profileFd != null) {
516 } catch (IOException e) {
525 static final class DumpComponentInfo {
526 ParcelFileDescriptor fd;
532 static final class ResultData {
534 List<ResultInfo> results;
535 public String toString() {
536 return "ResultData{token=" + token + " results" + results + "}";
540 static final class ContextCleanupInfo {
546 static final class DumpHeapData {
548 ParcelFileDescriptor fd;
551 static final class UpdateCompatibilityData {
553 CompatibilityInfo info;
556 static final class RequestAssistContextExtras {
557 IBinder activityToken;
558 IBinder requestToken;
562 private native void dumpGraphicsInfo(FileDescriptor fd);
564 private class ApplicationThread extends ApplicationThreadNative {
565 private static final String ONE_COUNT_COLUMN = "%21s %8d";
566 private static final String TWO_COUNT_COLUMNS = "%21s %8d %21s %8d";
567 private static final String DB_INFO_FORMAT = " %8s %8s %14s %14s %s";
569 private int mLastProcessState = -1;
571 private void updatePendingConfiguration(Configuration config) {
572 synchronized (mResourcesManager) {
573 if (mPendingConfiguration == null ||
574 mPendingConfiguration.isOtherSeqNewer(config)) {
575 mPendingConfiguration = config;
580 public final void schedulePauseActivity(IBinder token, boolean finished,
581 boolean userLeaving, int configChanges, boolean dontReport) {
583 finished ? H.PAUSE_ACTIVITY_FINISHING : H.PAUSE_ACTIVITY,
585 (userLeaving ? 1 : 0) | (dontReport ? 2 : 0),
589 public final void scheduleStopActivity(IBinder token, boolean showWindow,
592 showWindow ? H.STOP_ACTIVITY_SHOW : H.STOP_ACTIVITY_HIDE,
593 token, 0, configChanges);
596 public final void scheduleWindowVisibility(IBinder token, boolean showWindow) {
598 showWindow ? H.SHOW_WINDOW : H.HIDE_WINDOW,
602 public final void scheduleSleeping(IBinder token, boolean sleeping) {
603 sendMessage(H.SLEEPING, token, sleeping ? 1 : 0);
606 public final void scheduleResumeActivity(IBinder token, int processState,
607 boolean isForward, Bundle resumeArgs) {
608 updateProcessState(processState, false);
609 sendMessage(H.RESUME_ACTIVITY, token, isForward ? 1 : 0);
612 public final void scheduleSendResult(IBinder token, List<ResultInfo> results) {
613 ResultData res = new ResultData();
615 res.results = results;
616 sendMessage(H.SEND_RESULT, res);
619 // we use token to identify this activity without having to send the
620 // activity itself back to the activity manager. (matters more with ipc)
621 public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
622 ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo,
623 String referrer, IVoiceInteractor voiceInteractor, int procState, Bundle state,
624 PersistableBundle persistentState, List<ResultInfo> pendingResults,
625 List<ReferrerIntent> pendingNewIntents, boolean notResumed, boolean isForward,
626 ProfilerInfo profilerInfo) {
628 updateProcessState(procState, false);
630 ActivityClientRecord r = new ActivityClientRecord();
635 r.referrer = referrer;
636 r.voiceInteractor = voiceInteractor;
637 r.activityInfo = info;
638 r.compatInfo = compatInfo;
640 r.persistentState = persistentState;
642 r.pendingResults = pendingResults;
643 r.pendingIntents = pendingNewIntents;
645 r.startsNotResumed = notResumed;
646 r.isForward = isForward;
648 r.profilerInfo = profilerInfo;
650 updatePendingConfiguration(curConfig);
652 sendMessage(H.LAUNCH_ACTIVITY, r);
655 public final void scheduleRelaunchActivity(IBinder token,
656 List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents,
657 int configChanges, boolean notResumed, Configuration config) {
658 requestRelaunchActivity(token, pendingResults, pendingNewIntents,
659 configChanges, notResumed, config, true);
662 public final void scheduleNewIntent(List<ReferrerIntent> intents, IBinder token) {
663 NewIntentData data = new NewIntentData();
664 data.intents = intents;
667 sendMessage(H.NEW_INTENT, data);
670 public final void scheduleDestroyActivity(IBinder token, boolean finishing,
672 sendMessage(H.DESTROY_ACTIVITY, token, finishing ? 1 : 0,
676 public final void scheduleReceiver(Intent intent, ActivityInfo info,
677 CompatibilityInfo compatInfo, int resultCode, String data, Bundle extras,
678 boolean sync, int sendingUser, int processState) {
679 updateProcessState(processState, false);
680 ReceiverData r = new ReceiverData(intent, resultCode, data, extras,
681 sync, false, mAppThread.asBinder(), sendingUser);
683 r.compatInfo = compatInfo;
684 sendMessage(H.RECEIVER, r);
687 public final void scheduleCreateBackupAgent(ApplicationInfo app,
688 CompatibilityInfo compatInfo, int backupMode) {
689 CreateBackupAgentData d = new CreateBackupAgentData();
691 d.compatInfo = compatInfo;
692 d.backupMode = backupMode;
694 sendMessage(H.CREATE_BACKUP_AGENT, d);
697 public final void scheduleDestroyBackupAgent(ApplicationInfo app,
698 CompatibilityInfo compatInfo) {
699 CreateBackupAgentData d = new CreateBackupAgentData();
701 d.compatInfo = compatInfo;
703 sendMessage(H.DESTROY_BACKUP_AGENT, d);
706 public final void scheduleCreateService(IBinder token,
707 ServiceInfo info, CompatibilityInfo compatInfo, int processState) {
708 updateProcessState(processState, false);
709 CreateServiceData s = new CreateServiceData();
712 s.compatInfo = compatInfo;
714 sendMessage(H.CREATE_SERVICE, s);
717 public final void scheduleBindService(IBinder token, Intent intent,
718 boolean rebind, int processState) {
719 updateProcessState(processState, false);
720 BindServiceData s = new BindServiceData();
726 Slog.v(TAG, "scheduleBindService token=" + token + " intent=" + intent + " uid="
727 + Binder.getCallingUid() + " pid=" + Binder.getCallingPid());
728 sendMessage(H.BIND_SERVICE, s);
731 public final void scheduleUnbindService(IBinder token, Intent intent) {
732 BindServiceData s = new BindServiceData();
736 sendMessage(H.UNBIND_SERVICE, s);
739 public final void scheduleServiceArgs(IBinder token, boolean taskRemoved, int startId,
740 int flags ,Intent args) {
741 ServiceArgsData s = new ServiceArgsData();
743 s.taskRemoved = taskRemoved;
748 sendMessage(H.SERVICE_ARGS, s);
751 public final void scheduleStopService(IBinder token) {
752 sendMessage(H.STOP_SERVICE, token);
755 public final void bindApplication(String processName, ApplicationInfo appInfo,
756 List<ProviderInfo> providers, ComponentName instrumentationName,
757 ProfilerInfo profilerInfo, Bundle instrumentationArgs,
758 IInstrumentationWatcher instrumentationWatcher,
759 IUiAutomationConnection instrumentationUiConnection, int debugMode,
760 boolean enableOpenGlTrace, boolean isRestrictedBackupMode, boolean persistent,
761 Configuration config, CompatibilityInfo compatInfo, Map<String, IBinder> services,
762 Bundle coreSettings) {
764 if (services != null) {
765 // Setup the service cache in the ServiceManager
766 ServiceManager.initServiceCache(services);
769 setCoreSettings(coreSettings);
772 * Two possible indications that this package could be
773 * sharing its runtime with other packages:
775 * 1.) the sharedUserId attribute is set in the manifest,
776 * indicating a request to share a VM with other
777 * packages with the same sharedUserId.
779 * 2.) the application element of the manifest has an
780 * attribute specifying a non-default process name,
781 * indicating the desire to run in another packages VM.
783 * If sharing is enabled we do not have a unique application
784 * in a process and therefore cannot rely on the package
785 * name inside the runtime.
787 IPackageManager pm = getPackageManager();
788 android.content.pm.PackageInfo pi = null;
790 pi = pm.getPackageInfo(appInfo.packageName, 0, UserHandle.myUserId());
791 } catch (RemoteException e) {
794 boolean sharedUserIdSet = (pi.sharedUserId != null);
795 boolean processNameNotDefault =
796 (pi.applicationInfo != null &&
797 !appInfo.packageName.equals(pi.applicationInfo.processName));
798 boolean sharable = (sharedUserIdSet || processNameNotDefault);
800 // Tell the VMRuntime about the application, unless it is shared
803 VMRuntime.registerAppInfo(appInfo.packageName, appInfo.dataDir,
804 appInfo.processName);
808 AppBindData data = new AppBindData();
809 data.processName = processName;
810 data.appInfo = appInfo;
811 data.providers = providers;
812 data.instrumentationName = instrumentationName;
813 data.instrumentationArgs = instrumentationArgs;
814 data.instrumentationWatcher = instrumentationWatcher;
815 data.instrumentationUiAutomationConnection = instrumentationUiConnection;
816 data.debugMode = debugMode;
817 data.enableOpenGlTrace = enableOpenGlTrace;
818 data.restrictedBackupMode = isRestrictedBackupMode;
819 data.persistent = persistent;
820 data.config = config;
821 data.compatInfo = compatInfo;
822 data.initProfilerInfo = profilerInfo;
823 sendMessage(H.BIND_APPLICATION, data);
826 public final void scheduleExit() {
827 sendMessage(H.EXIT_APPLICATION, null);
830 public final void scheduleSuicide() {
831 sendMessage(H.SUICIDE, null);
834 public void scheduleConfigurationChanged(Configuration config) {
835 updatePendingConfiguration(config);
836 sendMessage(H.CONFIGURATION_CHANGED, config);
839 public void updateTimeZone() {
840 TimeZone.setDefault(null);
843 public void clearDnsCache() {
844 // a non-standard API to get this to libcore
845 InetAddress.clearDnsCache();
846 // Allow libcore to perform the necessary actions as it sees fit upon a network
847 // configuration change.
848 NetworkEventDispatcher.getInstance().onNetworkConfigurationChanged();
851 public void setHttpProxy(String host, String port, String exclList, Uri pacFileUrl) {
852 final Network network = ConnectivityManager.getProcessDefaultNetwork();
853 if (network != null) {
854 Proxy.setHttpProxySystemProperty(
855 ConnectivityManager.from(getSystemContext()).getDefaultProxy());
857 Proxy.setHttpProxySystemProperty(host, port, exclList, pacFileUrl);
861 public void processInBackground() {
862 mH.removeMessages(H.GC_WHEN_IDLE);
863 mH.sendMessage(mH.obtainMessage(H.GC_WHEN_IDLE));
866 public void dumpService(FileDescriptor fd, IBinder servicetoken, String[] args) {
867 DumpComponentInfo data = new DumpComponentInfo();
869 data.fd = ParcelFileDescriptor.dup(fd);
870 data.token = servicetoken;
872 sendMessage(H.DUMP_SERVICE, data, 0, 0, true /*async*/);
873 } catch (IOException e) {
874 Slog.w(TAG, "dumpService failed", e);
878 // This function exists to make sure all receiver dispatching is
879 // correctly ordered, since these are one-way calls and the binder driver
880 // applies transaction ordering per object for such calls.
881 public void scheduleRegisteredReceiver(IIntentReceiver receiver, Intent intent,
882 int resultCode, String dataStr, Bundle extras, boolean ordered,
883 boolean sticky, int sendingUser, int processState) throws RemoteException {
884 updateProcessState(processState, false);
885 receiver.performReceive(intent, resultCode, dataStr, extras, ordered,
886 sticky, sendingUser);
889 public void scheduleLowMemory() {
890 sendMessage(H.LOW_MEMORY, null);
893 public void scheduleActivityConfigurationChanged(IBinder token) {
894 sendMessage(H.ACTIVITY_CONFIGURATION_CHANGED, token);
897 public void profilerControl(boolean start, ProfilerInfo profilerInfo, int profileType) {
898 sendMessage(H.PROFILER_CONTROL, profilerInfo, start ? 1 : 0, profileType);
901 public void dumpHeap(boolean managed, String path, ParcelFileDescriptor fd) {
902 DumpHeapData dhd = new DumpHeapData();
905 sendMessage(H.DUMP_HEAP, dhd, managed ? 1 : 0, 0, true /*async*/);
908 public void setSchedulingGroup(int group) {
909 // Note: do this immediately, since going into the foreground
910 // should happen regardless of what pending work we have to do
911 // and the activity manager will wait for us to report back that
912 // we are done before sending us to the background.
914 Process.setProcessGroup(Process.myPid(), group);
915 } catch (Exception e) {
916 Slog.w(TAG, "Failed setting process group to " + group, e);
920 public void dispatchPackageBroadcast(int cmd, String[] packages) {
921 sendMessage(H.DISPATCH_PACKAGE_BROADCAST, packages, cmd);
924 public void scheduleCrash(String msg) {
925 sendMessage(H.SCHEDULE_CRASH, msg);
928 public void dumpActivity(FileDescriptor fd, IBinder activitytoken,
929 String prefix, String[] args) {
930 DumpComponentInfo data = new DumpComponentInfo();
932 data.fd = ParcelFileDescriptor.dup(fd);
933 data.token = activitytoken;
934 data.prefix = prefix;
936 sendMessage(H.DUMP_ACTIVITY, data, 0, 0, true /*async*/);
937 } catch (IOException e) {
938 Slog.w(TAG, "dumpActivity failed", e);
942 public void dumpProvider(FileDescriptor fd, IBinder providertoken,
944 DumpComponentInfo data = new DumpComponentInfo();
946 data.fd = ParcelFileDescriptor.dup(fd);
947 data.token = providertoken;
949 sendMessage(H.DUMP_PROVIDER, data, 0, 0, true /*async*/);
950 } catch (IOException e) {
951 Slog.w(TAG, "dumpProvider failed", e);
956 public void dumpMemInfo(FileDescriptor fd, Debug.MemoryInfo mem, boolean checkin,
957 boolean dumpFullInfo, boolean dumpDalvik, String[] args) {
958 FileOutputStream fout = new FileOutputStream(fd);
959 PrintWriter pw = new FastPrintWriter(fout);
961 dumpMemInfo(pw, mem, checkin, dumpFullInfo, dumpDalvik);
967 private void dumpMemInfo(PrintWriter pw, Debug.MemoryInfo memInfo, boolean checkin,
968 boolean dumpFullInfo, boolean dumpDalvik) {
969 long nativeMax = Debug.getNativeHeapSize() / 1024;
970 long nativeAllocated = Debug.getNativeHeapAllocatedSize() / 1024;
971 long nativeFree = Debug.getNativeHeapFreeSize() / 1024;
973 Runtime runtime = Runtime.getRuntime();
975 long dalvikMax = runtime.totalMemory() / 1024;
976 long dalvikFree = runtime.freeMemory() / 1024;
977 long dalvikAllocated = dalvikMax - dalvikFree;
978 long viewInstanceCount = ViewDebug.getViewInstanceCount();
979 long viewRootInstanceCount = ViewDebug.getViewRootImplCount();
980 long appContextInstanceCount = Debug.countInstancesOfClass(ContextImpl.class);
981 long activityInstanceCount = Debug.countInstancesOfClass(Activity.class);
982 int globalAssetCount = AssetManager.getGlobalAssetCount();
983 int globalAssetManagerCount = AssetManager.getGlobalAssetManagerCount();
984 int binderLocalObjectCount = Debug.getBinderLocalObjectCount();
985 int binderProxyObjectCount = Debug.getBinderProxyObjectCount();
986 int binderDeathObjectCount = Debug.getBinderDeathObjectCount();
987 long parcelSize = Parcel.getGlobalAllocSize();
988 long parcelCount = Parcel.getGlobalAllocCount();
989 long openSslSocketCount = Debug.countInstancesOfClass(OpenSSLSocketImpl.class);
990 SQLiteDebug.PagerStats stats = SQLiteDebug.getDatabaseInfo();
992 dumpMemInfoTable(pw, memInfo, checkin, dumpFullInfo, dumpDalvik, Process.myPid(),
993 (mBoundApplication != null) ? mBoundApplication.processName : "unknown",
994 nativeMax, nativeAllocated, nativeFree,
995 dalvikMax, dalvikAllocated, dalvikFree);
998 // NOTE: if you change anything significant below, also consider changing
999 // ACTIVITY_THREAD_CHECKIN_VERSION.
1002 pw.print(viewInstanceCount); pw.print(',');
1003 pw.print(viewRootInstanceCount); pw.print(',');
1004 pw.print(appContextInstanceCount); pw.print(',');
1005 pw.print(activityInstanceCount); pw.print(',');
1007 pw.print(globalAssetCount); pw.print(',');
1008 pw.print(globalAssetManagerCount); pw.print(',');
1009 pw.print(binderLocalObjectCount); pw.print(',');
1010 pw.print(binderProxyObjectCount); pw.print(',');
1012 pw.print(binderDeathObjectCount); pw.print(',');
1013 pw.print(openSslSocketCount); pw.print(',');
1016 pw.print(stats.memoryUsed / 1024); pw.print(',');
1017 pw.print(stats.memoryUsed / 1024); pw.print(',');
1018 pw.print(stats.pageCacheOverflow / 1024); pw.print(',');
1019 pw.print(stats.largestMemAlloc / 1024);
1020 for (int i = 0; i < stats.dbStats.size(); i++) {
1021 DbStats dbStats = stats.dbStats.get(i);
1022 pw.print(','); pw.print(dbStats.dbName);
1023 pw.print(','); pw.print(dbStats.pageSize);
1024 pw.print(','); pw.print(dbStats.dbSize);
1025 pw.print(','); pw.print(dbStats.lookaside);
1026 pw.print(','); pw.print(dbStats.cache);
1027 pw.print(','); pw.print(dbStats.cache);
1035 pw.println(" Objects");
1036 printRow(pw, TWO_COUNT_COLUMNS, "Views:", viewInstanceCount, "ViewRootImpl:",
1037 viewRootInstanceCount);
1039 printRow(pw, TWO_COUNT_COLUMNS, "AppContexts:", appContextInstanceCount,
1040 "Activities:", activityInstanceCount);
1042 printRow(pw, TWO_COUNT_COLUMNS, "Assets:", globalAssetCount,
1043 "AssetManagers:", globalAssetManagerCount);
1045 printRow(pw, TWO_COUNT_COLUMNS, "Local Binders:", binderLocalObjectCount,
1046 "Proxy Binders:", binderProxyObjectCount);
1047 printRow(pw, TWO_COUNT_COLUMNS, "Parcel memory:", parcelSize/1024,
1048 "Parcel count:", parcelCount);
1049 printRow(pw, TWO_COUNT_COLUMNS, "Death Recipients:", binderDeathObjectCount,
1050 "OpenSSL Sockets:", openSslSocketCount);
1055 printRow(pw, ONE_COUNT_COLUMN, "MEMORY_USED:", stats.memoryUsed / 1024);
1056 printRow(pw, TWO_COUNT_COLUMNS, "PAGECACHE_OVERFLOW:",
1057 stats.pageCacheOverflow / 1024, "MALLOC_SIZE:", stats.largestMemAlloc / 1024);
1059 int N = stats.dbStats.size();
1061 pw.println(" DATABASES");
1062 printRow(pw, " %8s %8s %14s %14s %s", "pgsz", "dbsz", "Lookaside(b)", "cache",
1064 for (int i = 0; i < N; i++) {
1065 DbStats dbStats = stats.dbStats.get(i);
1066 printRow(pw, DB_INFO_FORMAT,
1067 (dbStats.pageSize > 0) ? String.valueOf(dbStats.pageSize) : " ",
1068 (dbStats.dbSize > 0) ? String.valueOf(dbStats.dbSize) : " ",
1069 (dbStats.lookaside > 0) ? String.valueOf(dbStats.lookaside) : " ",
1070 dbStats.cache, dbStats.dbName);
1075 String assetAlloc = AssetManager.getAssetAllocations();
1076 if (assetAlloc != null) {
1078 pw.println(" Asset Allocations");
1079 pw.print(assetAlloc);
1084 public void dumpGfxInfo(FileDescriptor fd, String[] args) {
1085 dumpGraphicsInfo(fd);
1086 WindowManagerGlobal.getInstance().dumpGfxInfo(fd);
1090 public void dumpDbInfo(FileDescriptor fd, String[] args) {
1091 PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd));
1092 PrintWriterPrinter printer = new PrintWriterPrinter(pw);
1093 SQLiteDebug.dump(printer, args);
1098 public void unstableProviderDied(IBinder provider) {
1099 sendMessage(H.UNSTABLE_PROVIDER_DIED, provider);
1103 public void requestAssistContextExtras(IBinder activityToken, IBinder requestToken,
1105 RequestAssistContextExtras cmd = new RequestAssistContextExtras();
1106 cmd.activityToken = activityToken;
1107 cmd.requestToken = requestToken;
1108 cmd.requestType = requestType;
1109 sendMessage(H.REQUEST_ASSIST_CONTEXT_EXTRAS, cmd);
1112 public void setCoreSettings(Bundle coreSettings) {
1113 sendMessage(H.SET_CORE_SETTINGS, coreSettings);
1116 public void updatePackageCompatibilityInfo(String pkg, CompatibilityInfo info) {
1117 UpdateCompatibilityData ucd = new UpdateCompatibilityData();
1120 sendMessage(H.UPDATE_PACKAGE_COMPATIBILITY_INFO, ucd);
1123 public void scheduleTrimMemory(int level) {
1124 sendMessage(H.TRIM_MEMORY, null, level);
1127 public void scheduleTranslucentConversionComplete(IBinder token, boolean drawComplete) {
1128 sendMessage(H.TRANSLUCENT_CONVERSION_COMPLETE, token, drawComplete ? 1 : 0);
1131 public void scheduleOnNewActivityOptions(IBinder token, ActivityOptions options) {
1132 sendMessage(H.ON_NEW_ACTIVITY_OPTIONS,
1133 new Pair<IBinder, ActivityOptions>(token, options));
1136 public void setProcessState(int state) {
1137 updateProcessState(state, true);
1140 public void updateProcessState(int processState, boolean fromIpc) {
1141 synchronized (this) {
1142 if (mLastProcessState != processState) {
1143 mLastProcessState = processState;
1144 // Update Dalvik state based on ActivityManager.PROCESS_STATE_* constants.
1145 final int DALVIK_PROCESS_STATE_JANK_PERCEPTIBLE = 0;
1146 final int DALVIK_PROCESS_STATE_JANK_IMPERCEPTIBLE = 1;
1147 int dalvikProcessState = DALVIK_PROCESS_STATE_JANK_IMPERCEPTIBLE;
1148 // TODO: Tune this since things like gmail sync are important background but not jank perceptible.
1149 if (processState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
1150 dalvikProcessState = DALVIK_PROCESS_STATE_JANK_PERCEPTIBLE;
1152 VMRuntime.getRuntime().updateProcessState(dalvikProcessState);
1154 Slog.i(TAG, "******************* PROCESS STATE CHANGED TO: " + processState
1155 + (fromIpc ? " (from ipc": ""));
1162 public void scheduleInstallProvider(ProviderInfo provider) {
1163 sendMessage(H.INSTALL_PROVIDER, provider);
1167 public final void updateTimePrefs(boolean is24Hour) {
1168 DateFormat.set24HourTimePref(is24Hour);
1172 public void scheduleCancelVisibleBehind(IBinder token) {
1173 sendMessage(H.CANCEL_VISIBLE_BEHIND, token);
1177 public void scheduleBackgroundVisibleBehindChanged(IBinder token, boolean visible) {
1178 sendMessage(H.BACKGROUND_VISIBLE_BEHIND_CHANGED, token, visible ? 1 : 0);
1181 public void scheduleEnterAnimationComplete(IBinder token) {
1182 sendMessage(H.ENTER_ANIMATION_COMPLETE, token);
1186 private class H extends Handler {
1187 public static final int LAUNCH_ACTIVITY = 100;
1188 public static final int PAUSE_ACTIVITY = 101;
1189 public static final int PAUSE_ACTIVITY_FINISHING= 102;
1190 public static final int STOP_ACTIVITY_SHOW = 103;
1191 public static final int STOP_ACTIVITY_HIDE = 104;
1192 public static final int SHOW_WINDOW = 105;
1193 public static final int HIDE_WINDOW = 106;
1194 public static final int RESUME_ACTIVITY = 107;
1195 public static final int SEND_RESULT = 108;
1196 public static final int DESTROY_ACTIVITY = 109;
1197 public static final int BIND_APPLICATION = 110;
1198 public static final int EXIT_APPLICATION = 111;
1199 public static final int NEW_INTENT = 112;
1200 public static final int RECEIVER = 113;
1201 public static final int CREATE_SERVICE = 114;
1202 public static final int SERVICE_ARGS = 115;
1203 public static final int STOP_SERVICE = 116;
1205 public static final int CONFIGURATION_CHANGED = 118;
1206 public static final int CLEAN_UP_CONTEXT = 119;
1207 public static final int GC_WHEN_IDLE = 120;
1208 public static final int BIND_SERVICE = 121;
1209 public static final int UNBIND_SERVICE = 122;
1210 public static final int DUMP_SERVICE = 123;
1211 public static final int LOW_MEMORY = 124;
1212 public static final int ACTIVITY_CONFIGURATION_CHANGED = 125;
1213 public static final int RELAUNCH_ACTIVITY = 126;
1214 public static final int PROFILER_CONTROL = 127;
1215 public static final int CREATE_BACKUP_AGENT = 128;
1216 public static final int DESTROY_BACKUP_AGENT = 129;
1217 public static final int SUICIDE = 130;
1218 public static final int REMOVE_PROVIDER = 131;
1219 public static final int ENABLE_JIT = 132;
1220 public static final int DISPATCH_PACKAGE_BROADCAST = 133;
1221 public static final int SCHEDULE_CRASH = 134;
1222 public static final int DUMP_HEAP = 135;
1223 public static final int DUMP_ACTIVITY = 136;
1224 public static final int SLEEPING = 137;
1225 public static final int SET_CORE_SETTINGS = 138;
1226 public static final int UPDATE_PACKAGE_COMPATIBILITY_INFO = 139;
1227 public static final int TRIM_MEMORY = 140;
1228 public static final int DUMP_PROVIDER = 141;
1229 public static final int UNSTABLE_PROVIDER_DIED = 142;
1230 public static final int REQUEST_ASSIST_CONTEXT_EXTRAS = 143;
1231 public static final int TRANSLUCENT_CONVERSION_COMPLETE = 144;
1232 public static final int INSTALL_PROVIDER = 145;
1233 public static final int ON_NEW_ACTIVITY_OPTIONS = 146;
1234 public static final int CANCEL_VISIBLE_BEHIND = 147;
1235 public static final int BACKGROUND_VISIBLE_BEHIND_CHANGED = 148;
1236 public static final int ENTER_ANIMATION_COMPLETE = 149;
1238 String codeToString(int code) {
1239 if (DEBUG_MESSAGES) {
1241 case LAUNCH_ACTIVITY: return "LAUNCH_ACTIVITY";
1242 case PAUSE_ACTIVITY: return "PAUSE_ACTIVITY";
1243 case PAUSE_ACTIVITY_FINISHING: return "PAUSE_ACTIVITY_FINISHING";
1244 case STOP_ACTIVITY_SHOW: return "STOP_ACTIVITY_SHOW";
1245 case STOP_ACTIVITY_HIDE: return "STOP_ACTIVITY_HIDE";
1246 case SHOW_WINDOW: return "SHOW_WINDOW";
1247 case HIDE_WINDOW: return "HIDE_WINDOW";
1248 case RESUME_ACTIVITY: return "RESUME_ACTIVITY";
1249 case SEND_RESULT: return "SEND_RESULT";
1250 case DESTROY_ACTIVITY: return "DESTROY_ACTIVITY";
1251 case BIND_APPLICATION: return "BIND_APPLICATION";
1252 case EXIT_APPLICATION: return "EXIT_APPLICATION";
1253 case NEW_INTENT: return "NEW_INTENT";
1254 case RECEIVER: return "RECEIVER";
1255 case CREATE_SERVICE: return "CREATE_SERVICE";
1256 case SERVICE_ARGS: return "SERVICE_ARGS";
1257 case STOP_SERVICE: return "STOP_SERVICE";
1258 case CONFIGURATION_CHANGED: return "CONFIGURATION_CHANGED";
1259 case CLEAN_UP_CONTEXT: return "CLEAN_UP_CONTEXT";
1260 case GC_WHEN_IDLE: return "GC_WHEN_IDLE";
1261 case BIND_SERVICE: return "BIND_SERVICE";
1262 case UNBIND_SERVICE: return "UNBIND_SERVICE";
1263 case DUMP_SERVICE: return "DUMP_SERVICE";
1264 case LOW_MEMORY: return "LOW_MEMORY";
1265 case ACTIVITY_CONFIGURATION_CHANGED: return "ACTIVITY_CONFIGURATION_CHANGED";
1266 case RELAUNCH_ACTIVITY: return "RELAUNCH_ACTIVITY";
1267 case PROFILER_CONTROL: return "PROFILER_CONTROL";
1268 case CREATE_BACKUP_AGENT: return "CREATE_BACKUP_AGENT";
1269 case DESTROY_BACKUP_AGENT: return "DESTROY_BACKUP_AGENT";
1270 case SUICIDE: return "SUICIDE";
1271 case REMOVE_PROVIDER: return "REMOVE_PROVIDER";
1272 case ENABLE_JIT: return "ENABLE_JIT";
1273 case DISPATCH_PACKAGE_BROADCAST: return "DISPATCH_PACKAGE_BROADCAST";
1274 case SCHEDULE_CRASH: return "SCHEDULE_CRASH";
1275 case DUMP_HEAP: return "DUMP_HEAP";
1276 case DUMP_ACTIVITY: return "DUMP_ACTIVITY";
1277 case SLEEPING: return "SLEEPING";
1278 case SET_CORE_SETTINGS: return "SET_CORE_SETTINGS";
1279 case UPDATE_PACKAGE_COMPATIBILITY_INFO: return "UPDATE_PACKAGE_COMPATIBILITY_INFO";
1280 case TRIM_MEMORY: return "TRIM_MEMORY";
1281 case DUMP_PROVIDER: return "DUMP_PROVIDER";
1282 case UNSTABLE_PROVIDER_DIED: return "UNSTABLE_PROVIDER_DIED";
1283 case REQUEST_ASSIST_CONTEXT_EXTRAS: return "REQUEST_ASSIST_CONTEXT_EXTRAS";
1284 case TRANSLUCENT_CONVERSION_COMPLETE: return "TRANSLUCENT_CONVERSION_COMPLETE";
1285 case INSTALL_PROVIDER: return "INSTALL_PROVIDER";
1286 case ON_NEW_ACTIVITY_OPTIONS: return "ON_NEW_ACTIVITY_OPTIONS";
1287 case CANCEL_VISIBLE_BEHIND: return "CANCEL_VISIBLE_BEHIND";
1288 case BACKGROUND_VISIBLE_BEHIND_CHANGED: return "BACKGROUND_VISIBLE_BEHIND_CHANGED";
1289 case ENTER_ANIMATION_COMPLETE: return "ENTER_ANIMATION_COMPLETE";
1292 return Integer.toString(code);
1294 public void handleMessage(Message msg) {
1295 if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
1297 case LAUNCH_ACTIVITY: {
1298 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
1299 final ActivityClientRecord r = (ActivityClientRecord) msg.obj;
1301 r.packageInfo = getPackageInfoNoCheck(
1302 r.activityInfo.applicationInfo, r.compatInfo);
1303 handleLaunchActivity(r, null);
1304 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1306 case RELAUNCH_ACTIVITY: {
1307 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityRestart");
1308 ActivityClientRecord r = (ActivityClientRecord)msg.obj;
1309 handleRelaunchActivity(r);
1310 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1312 case PAUSE_ACTIVITY:
1313 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
1314 handlePauseActivity((IBinder)msg.obj, false, (msg.arg1&1) != 0, msg.arg2,
1317 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1319 case PAUSE_ACTIVITY_FINISHING:
1320 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
1321 handlePauseActivity((IBinder)msg.obj, true, (msg.arg1&1) != 0, msg.arg2,
1323 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1325 case STOP_ACTIVITY_SHOW:
1326 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStop");
1327 handleStopActivity((IBinder)msg.obj, true, msg.arg2);
1328 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1330 case STOP_ACTIVITY_HIDE:
1331 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStop");
1332 handleStopActivity((IBinder)msg.obj, false, msg.arg2);
1333 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1336 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityShowWindow");
1337 handleWindowVisibility((IBinder)msg.obj, true);
1338 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1341 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityHideWindow");
1342 handleWindowVisibility((IBinder)msg.obj, false);
1343 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1345 case RESUME_ACTIVITY:
1346 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityResume");
1347 handleResumeActivity((IBinder) msg.obj, true, msg.arg1 != 0, true);
1348 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1351 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityDeliverResult");
1352 handleSendResult((ResultData)msg.obj);
1353 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1355 case DESTROY_ACTIVITY:
1356 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityDestroy");
1357 handleDestroyActivity((IBinder)msg.obj, msg.arg1 != 0,
1359 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1361 case BIND_APPLICATION:
1362 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
1363 AppBindData data = (AppBindData)msg.obj;
1364 handleBindApplication(data);
1365 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1367 case EXIT_APPLICATION:
1368 if (mInitialApplication != null) {
1369 mInitialApplication.onTerminate();
1371 Looper.myLooper().quit();
1374 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityNewIntent");
1375 handleNewIntent((NewIntentData)msg.obj);
1376 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1379 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "broadcastReceiveComp");
1380 handleReceiver((ReceiverData)msg.obj);
1382 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1384 case CREATE_SERVICE:
1385 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceCreate");
1386 handleCreateService((CreateServiceData)msg.obj);
1387 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1390 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceBind");
1391 handleBindService((BindServiceData)msg.obj);
1392 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1394 case UNBIND_SERVICE:
1395 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceUnbind");
1396 handleUnbindService((BindServiceData)msg.obj);
1397 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1400 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceStart");
1401 handleServiceArgs((ServiceArgsData)msg.obj);
1402 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1405 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceStop");
1406 handleStopService((IBinder)msg.obj);
1408 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1410 case CONFIGURATION_CHANGED:
1411 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "configChanged");
1412 mCurDefaultDisplayDpi = ((Configuration)msg.obj).densityDpi;
1413 handleConfigurationChanged((Configuration)msg.obj, null);
1414 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1416 case CLEAN_UP_CONTEXT:
1417 ContextCleanupInfo cci = (ContextCleanupInfo)msg.obj;
1418 cci.context.performFinalCleanup(cci.who, cci.what);
1424 handleDumpService((DumpComponentInfo)msg.obj);
1427 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "lowMemory");
1429 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1431 case ACTIVITY_CONFIGURATION_CHANGED:
1432 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityConfigChanged");
1433 handleActivityConfigurationChanged((IBinder)msg.obj);
1434 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1436 case PROFILER_CONTROL:
1437 handleProfilerControl(msg.arg1 != 0, (ProfilerInfo)msg.obj, msg.arg2);
1439 case CREATE_BACKUP_AGENT:
1440 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "backupCreateAgent");
1441 handleCreateBackupAgent((CreateBackupAgentData)msg.obj);
1442 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1444 case DESTROY_BACKUP_AGENT:
1445 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "backupDestroyAgent");
1446 handleDestroyBackupAgent((CreateBackupAgentData)msg.obj);
1447 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1450 Process.killProcess(Process.myPid());
1452 case REMOVE_PROVIDER:
1453 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "providerRemove");
1454 completeRemoveProvider((ProviderRefCount)msg.obj);
1455 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1460 case DISPATCH_PACKAGE_BROADCAST:
1461 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "broadcastPackage");
1462 handleDispatchPackageBroadcast(msg.arg1, (String[])msg.obj);
1463 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1465 case SCHEDULE_CRASH:
1466 throw new RemoteServiceException((String)msg.obj);
1468 handleDumpHeap(msg.arg1 != 0, (DumpHeapData)msg.obj);
1471 handleDumpActivity((DumpComponentInfo)msg.obj);
1474 handleDumpProvider((DumpComponentInfo)msg.obj);
1477 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "sleeping");
1478 handleSleeping((IBinder)msg.obj, msg.arg1 != 0);
1479 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1481 case SET_CORE_SETTINGS:
1482 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "setCoreSettings");
1483 handleSetCoreSettings((Bundle) msg.obj);
1484 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1486 case UPDATE_PACKAGE_COMPATIBILITY_INFO:
1487 handleUpdatePackageCompatibilityInfo((UpdateCompatibilityData)msg.obj);
1490 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "trimMemory");
1491 handleTrimMemory(msg.arg1);
1492 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1494 case UNSTABLE_PROVIDER_DIED:
1495 handleUnstableProviderDied((IBinder)msg.obj, false);
1497 case REQUEST_ASSIST_CONTEXT_EXTRAS:
1498 handleRequestAssistContextExtras((RequestAssistContextExtras)msg.obj);
1500 case TRANSLUCENT_CONVERSION_COMPLETE:
1501 handleTranslucentConversionComplete((IBinder)msg.obj, msg.arg1 == 1);
1503 case INSTALL_PROVIDER:
1504 handleInstallProvider((ProviderInfo) msg.obj);
1506 case ON_NEW_ACTIVITY_OPTIONS:
1507 Pair<IBinder, ActivityOptions> pair = (Pair<IBinder, ActivityOptions>) msg.obj;
1508 onNewActivityOptions(pair.first, pair.second);
1510 case CANCEL_VISIBLE_BEHIND:
1511 handleCancelVisibleBehind((IBinder) msg.obj);
1513 case BACKGROUND_VISIBLE_BEHIND_CHANGED:
1514 handleOnBackgroundVisibleBehindChanged((IBinder) msg.obj, msg.arg1 > 0);
1516 case ENTER_ANIMATION_COMPLETE:
1517 handleEnterAnimationComplete((IBinder) msg.obj);
1520 if (DEBUG_MESSAGES) Slog.v(TAG, "<<< done: " + codeToString(msg.what));
1523 private void maybeSnapshot() {
1524 if (mBoundApplication != null && SamplingProfilerIntegration.isEnabled()) {
1525 // convert the *private* ActivityThread.PackageInfo to *public* known
1526 // android.content.pm.PackageInfo
1527 String packageName = mBoundApplication.info.mPackageName;
1528 android.content.pm.PackageInfo packageInfo = null;
1530 Context context = getSystemContext();
1531 if(context == null) {
1532 Log.e(TAG, "cannot get a valid context");
1535 PackageManager pm = context.getPackageManager();
1537 Log.e(TAG, "cannot get a valid PackageManager");
1540 packageInfo = pm.getPackageInfo(
1541 packageName, PackageManager.GET_ACTIVITIES);
1542 } catch (NameNotFoundException e) {
1543 Log.e(TAG, "cannot get package info for " + packageName, e);
1545 SamplingProfilerIntegration.writeSnapshot(mBoundApplication.processName, packageInfo);
1550 private class Idler implements MessageQueue.IdleHandler {
1552 public final boolean queueIdle() {
1553 ActivityClientRecord a = mNewActivities;
1554 boolean stopProfiling = false;
1555 if (mBoundApplication != null && mProfiler.profileFd != null
1556 && mProfiler.autoStopProfiler) {
1557 stopProfiling = true;
1560 mNewActivities = null;
1561 IActivityManager am = ActivityManagerNative.getDefault();
1562 ActivityClientRecord prev;
1564 if (localLOGV) Slog.v(
1565 TAG, "Reporting idle of " + a +
1567 (a.activity != null && a.activity.mFinished));
1568 if (a.activity != null && !a.activity.mFinished) {
1570 am.activityIdle(a.token, a.createdConfig, stopProfiling);
1571 a.createdConfig = null;
1572 } catch (RemoteException ex) {
1578 prev.nextIdle = null;
1579 } while (a != null);
1581 if (stopProfiling) {
1582 mProfiler.stopProfiling();
1589 final class GcIdler implements MessageQueue.IdleHandler {
1591 public final boolean queueIdle() {
1597 public static ActivityThread currentActivityThread() {
1598 return sCurrentActivityThread;
1601 public static String currentPackageName() {
1602 ActivityThread am = currentActivityThread();
1603 return (am != null && am.mBoundApplication != null)
1604 ? am.mBoundApplication.appInfo.packageName : null;
1607 public static String currentProcessName() {
1608 ActivityThread am = currentActivityThread();
1609 return (am != null && am.mBoundApplication != null)
1610 ? am.mBoundApplication.processName : null;
1613 public static Application currentApplication() {
1614 ActivityThread am = currentActivityThread();
1615 return am != null ? am.mInitialApplication : null;
1618 public static IPackageManager getPackageManager() {
1619 if (sPackageManager != null) {
1620 //Slog.v("PackageManager", "returning cur default = " + sPackageManager);
1621 return sPackageManager;
1623 IBinder b = ServiceManager.getService("package");
1624 //Slog.v("PackageManager", "default service binder = " + b);
1625 sPackageManager = IPackageManager.Stub.asInterface(b);
1626 //Slog.v("PackageManager", "default service = " + sPackageManager);
1627 return sPackageManager;
1630 private Configuration mMainThreadConfig = new Configuration();
1631 Configuration applyConfigCompatMainThread(int displayDensity, Configuration config,
1632 CompatibilityInfo compat) {
1633 if (config == null) {
1636 if (!compat.supportsScreen()) {
1637 mMainThreadConfig.setTo(config);
1638 config = mMainThreadConfig;
1639 compat.applyToConfiguration(displayDensity, config);
1645 * Creates the top level resources for the given package.
1647 Resources getTopLevelResources(String resDir, String[] splitResDirs, String[] overlayDirs,
1648 String[] libDirs, int displayId, Configuration overrideConfiguration,
1649 LoadedApk pkgInfo) {
1650 return mResourcesManager.getTopLevelResources(resDir, splitResDirs, overlayDirs, libDirs,
1651 displayId, overrideConfiguration, pkgInfo.getCompatibilityInfo(), null);
1654 final Handler getHandler() {
1658 public final LoadedApk getPackageInfo(String packageName, CompatibilityInfo compatInfo,
1660 return getPackageInfo(packageName, compatInfo, flags, UserHandle.myUserId());
1663 public final LoadedApk getPackageInfo(String packageName, CompatibilityInfo compatInfo,
1664 int flags, int userId) {
1665 synchronized (mResourcesManager) {
1666 WeakReference<LoadedApk> ref;
1667 if ((flags&Context.CONTEXT_INCLUDE_CODE) != 0) {
1668 ref = mPackages.get(packageName);
1670 ref = mResourcePackages.get(packageName);
1672 LoadedApk packageInfo = ref != null ? ref.get() : null;
1673 //Slog.i(TAG, "getPackageInfo " + packageName + ": " + packageInfo);
1674 //if (packageInfo != null) Slog.i(TAG, "isUptoDate " + packageInfo.mResDir
1675 // + ": " + packageInfo.mResources.getAssets().isUpToDate());
1676 if (packageInfo != null && (packageInfo.mResources == null
1677 || packageInfo.mResources.getAssets().isUpToDate())) {
1678 if (packageInfo.isSecurityViolation()
1679 && (flags&Context.CONTEXT_IGNORE_SECURITY) == 0) {
1680 throw new SecurityException(
1681 "Requesting code from " + packageName
1682 + " to be run in process "
1683 + mBoundApplication.processName
1684 + "/" + mBoundApplication.appInfo.uid);
1690 ApplicationInfo ai = null;
1692 ai = getPackageManager().getApplicationInfo(packageName,
1693 PackageManager.GET_SHARED_LIBRARY_FILES, userId);
1694 } catch (RemoteException e) {
1699 return getPackageInfo(ai, compatInfo, flags);
1705 public final LoadedApk getPackageInfo(ApplicationInfo ai, CompatibilityInfo compatInfo,
1707 boolean includeCode = (flags&Context.CONTEXT_INCLUDE_CODE) != 0;
1708 boolean securityViolation = includeCode && ai.uid != 0
1709 && ai.uid != Process.SYSTEM_UID && (mBoundApplication != null
1710 ? !UserHandle.isSameApp(ai.uid, mBoundApplication.appInfo.uid)
1712 boolean registerPackage = includeCode && (flags&Context.CONTEXT_REGISTER_PACKAGE) != 0;
1713 if ((flags&(Context.CONTEXT_INCLUDE_CODE
1714 |Context.CONTEXT_IGNORE_SECURITY))
1715 == Context.CONTEXT_INCLUDE_CODE) {
1716 if (securityViolation) {
1717 String msg = "Requesting code from " + ai.packageName
1718 + " (with uid " + ai.uid + ")";
1719 if (mBoundApplication != null) {
1720 msg = msg + " to be run in process "
1721 + mBoundApplication.processName + " (with uid "
1722 + mBoundApplication.appInfo.uid + ")";
1724 throw new SecurityException(msg);
1727 return getPackageInfo(ai, compatInfo, null, securityViolation, includeCode,
1731 public final LoadedApk getPackageInfoNoCheck(ApplicationInfo ai,
1732 CompatibilityInfo compatInfo) {
1733 return getPackageInfo(ai, compatInfo, null, false, true, false);
1736 public final LoadedApk peekPackageInfo(String packageName, boolean includeCode) {
1737 synchronized (mResourcesManager) {
1738 WeakReference<LoadedApk> ref;
1740 ref = mPackages.get(packageName);
1742 ref = mResourcePackages.get(packageName);
1744 return ref != null ? ref.get() : null;
1748 private LoadedApk getPackageInfo(ApplicationInfo aInfo, CompatibilityInfo compatInfo,
1749 ClassLoader baseLoader, boolean securityViolation, boolean includeCode,
1750 boolean registerPackage) {
1751 synchronized (mResourcesManager) {
1752 WeakReference<LoadedApk> ref;
1754 ref = mPackages.get(aInfo.packageName);
1756 ref = mResourcePackages.get(aInfo.packageName);
1758 LoadedApk packageInfo = ref != null ? ref.get() : null;
1759 if (packageInfo == null || (packageInfo.mResources != null
1760 && !packageInfo.mResources.getAssets().isUpToDate())) {
1761 if (localLOGV) Slog.v(TAG, (includeCode ? "Loading code package "
1762 : "Loading resource-only package ") + aInfo.packageName
1763 + " (in " + (mBoundApplication != null
1764 ? mBoundApplication.processName : null)
1767 new LoadedApk(this, aInfo, compatInfo, baseLoader,
1768 securityViolation, includeCode &&
1769 (aInfo.flags&ApplicationInfo.FLAG_HAS_CODE) != 0, registerPackage);
1771 if (mSystemThread && "android".equals(aInfo.packageName)) {
1772 packageInfo.installSystemApplicationInfo(aInfo,
1773 getSystemContext().mPackageInfo.getClassLoader());
1777 mPackages.put(aInfo.packageName,
1778 new WeakReference<LoadedApk>(packageInfo));
1780 mResourcePackages.put(aInfo.packageName,
1781 new WeakReference<LoadedApk>(packageInfo));
1789 mResourcesManager = ResourcesManager.getInstance();
1792 public ApplicationThread getApplicationThread()
1797 public Instrumentation getInstrumentation()
1799 return mInstrumentation;
1802 public boolean isProfiling() {
1803 return mProfiler != null && mProfiler.profileFile != null
1804 && mProfiler.profileFd == null;
1807 public String getProfileFilePath() {
1808 return mProfiler.profileFile;
1811 public Looper getLooper() {
1815 public Application getApplication() {
1816 return mInitialApplication;
1819 public String getProcessName() {
1820 return mBoundApplication.processName;
1823 public ContextImpl getSystemContext() {
1824 synchronized (this) {
1825 if (mSystemContext == null) {
1826 mSystemContext = ContextImpl.createSystemContext(this);
1828 return mSystemContext;
1832 public void installSystemApplicationInfo(ApplicationInfo info, ClassLoader classLoader) {
1833 synchronized (this) {
1834 getSystemContext().installSystemApplicationInfo(info, classLoader);
1836 // give ourselves a default profiler
1837 mProfiler = new Profiler();
1841 void ensureJitEnabled() {
1844 dalvik.system.VMRuntime.getRuntime().startJitCompilation();
1848 void scheduleGcIdler() {
1849 if (!mGcIdlerScheduled) {
1850 mGcIdlerScheduled = true;
1851 Looper.myQueue().addIdleHandler(mGcIdler);
1853 mH.removeMessages(H.GC_WHEN_IDLE);
1856 void unscheduleGcIdler() {
1857 if (mGcIdlerScheduled) {
1858 mGcIdlerScheduled = false;
1859 Looper.myQueue().removeIdleHandler(mGcIdler);
1861 mH.removeMessages(H.GC_WHEN_IDLE);
1864 void doGcIfNeeded() {
1865 mGcIdlerScheduled = false;
1866 final long now = SystemClock.uptimeMillis();
1867 //Slog.i(TAG, "**** WE MIGHT WANT TO GC: then=" + Binder.getLastGcTime()
1868 // + "m now=" + now);
1869 if ((BinderInternal.getLastGcTime()+MIN_TIME_BETWEEN_GCS) < now) {
1870 //Slog.i(TAG, "**** WE DO, WE DO WANT TO GC!");
1871 BinderInternal.forceGc("bg");
1875 private static final String HEAP_FULL_COLUMN
1876 = "%13s %8s %8s %8s %8s %8s %8s %8s %8s %8s %8s";
1877 private static final String HEAP_COLUMN
1878 = "%13s %8s %8s %8s %8s %8s %8s %8s";
1880 // Formatting for checkin service - update version if row format changes
1881 private static final int ACTIVITY_THREAD_CHECKIN_VERSION = 3;
1883 static void printRow(PrintWriter pw, String format, Object...objs) {
1884 pw.println(String.format(format, objs));
1887 public static void dumpMemInfoTable(PrintWriter pw, Debug.MemoryInfo memInfo, boolean checkin,
1888 boolean dumpFullInfo, boolean dumpDalvik, int pid, String processName,
1889 long nativeMax, long nativeAllocated, long nativeFree,
1890 long dalvikMax, long dalvikAllocated, long dalvikFree) {
1892 // For checkin, we print one long comma-separated list of values
1894 // NOTE: if you change anything significant below, also consider changing
1895 // ACTIVITY_THREAD_CHECKIN_VERSION.
1898 pw.print(ACTIVITY_THREAD_CHECKIN_VERSION); pw.print(',');
1899 pw.print(pid); pw.print(',');
1900 pw.print(processName); pw.print(',');
1903 pw.print(nativeMax); pw.print(',');
1904 pw.print(dalvikMax); pw.print(',');
1906 pw.print(nativeMax + dalvikMax); pw.print(',');
1908 // Heap info - allocated
1909 pw.print(nativeAllocated); pw.print(',');
1910 pw.print(dalvikAllocated); pw.print(',');
1912 pw.print(nativeAllocated + dalvikAllocated); pw.print(',');
1915 pw.print(nativeFree); pw.print(',');
1916 pw.print(dalvikFree); pw.print(',');
1918 pw.print(nativeFree + dalvikFree); pw.print(',');
1920 // Heap info - proportional set size
1921 pw.print(memInfo.nativePss); pw.print(',');
1922 pw.print(memInfo.dalvikPss); pw.print(',');
1923 pw.print(memInfo.otherPss); pw.print(',');
1924 pw.print(memInfo.getTotalPss()); pw.print(',');
1926 // Heap info - swappable set size
1927 pw.print(memInfo.nativeSwappablePss); pw.print(',');
1928 pw.print(memInfo.dalvikSwappablePss); pw.print(',');
1929 pw.print(memInfo.otherSwappablePss); pw.print(',');
1930 pw.print(memInfo.getTotalSwappablePss()); pw.print(',');
1932 // Heap info - shared dirty
1933 pw.print(memInfo.nativeSharedDirty); pw.print(',');
1934 pw.print(memInfo.dalvikSharedDirty); pw.print(',');
1935 pw.print(memInfo.otherSharedDirty); pw.print(',');
1936 pw.print(memInfo.getTotalSharedDirty()); pw.print(',');
1938 // Heap info - shared clean
1939 pw.print(memInfo.nativeSharedClean); pw.print(',');
1940 pw.print(memInfo.dalvikSharedClean); pw.print(',');
1941 pw.print(memInfo.otherSharedClean); pw.print(',');
1942 pw.print(memInfo.getTotalSharedClean()); pw.print(',');
1944 // Heap info - private Dirty
1945 pw.print(memInfo.nativePrivateDirty); pw.print(',');
1946 pw.print(memInfo.dalvikPrivateDirty); pw.print(',');
1947 pw.print(memInfo.otherPrivateDirty); pw.print(',');
1948 pw.print(memInfo.getTotalPrivateDirty()); pw.print(',');
1950 // Heap info - private Clean
1951 pw.print(memInfo.nativePrivateClean); pw.print(',');
1952 pw.print(memInfo.dalvikPrivateClean); pw.print(',');
1953 pw.print(memInfo.otherPrivateClean); pw.print(',');
1954 pw.print(memInfo.getTotalPrivateClean()); pw.print(',');
1956 // Heap info - other areas
1957 for (int i=0; i<Debug.MemoryInfo.NUM_OTHER_STATS; i++) {
1958 pw.print(Debug.MemoryInfo.getOtherLabel(i)); pw.print(',');
1959 pw.print(memInfo.getOtherPss(i)); pw.print(',');
1960 pw.print(memInfo.getOtherSwappablePss(i)); pw.print(',');
1961 pw.print(memInfo.getOtherSharedDirty(i)); pw.print(',');
1962 pw.print(memInfo.getOtherSharedClean(i)); pw.print(',');
1963 pw.print(memInfo.getOtherPrivateDirty(i)); pw.print(',');
1964 pw.print(memInfo.getOtherPrivateClean(i)); pw.print(',');
1969 // otherwise, show human-readable format
1971 printRow(pw, HEAP_FULL_COLUMN, "", "Pss", "Pss", "Shared", "Private",
1972 "Shared", "Private", "Swapped", "Heap", "Heap", "Heap");
1973 printRow(pw, HEAP_FULL_COLUMN, "", "Total", "Clean", "Dirty", "Dirty",
1974 "Clean", "Clean", "Dirty", "Size", "Alloc", "Free");
1975 printRow(pw, HEAP_FULL_COLUMN, "", "------", "------", "------", "------",
1976 "------", "------", "------", "------", "------", "------");
1977 printRow(pw, HEAP_FULL_COLUMN, "Native Heap", memInfo.nativePss,
1978 memInfo.nativeSwappablePss, memInfo.nativeSharedDirty,
1979 memInfo.nativePrivateDirty, memInfo.nativeSharedClean,
1980 memInfo.nativePrivateClean, memInfo.nativeSwappedOut,
1981 nativeMax, nativeAllocated, nativeFree);
1982 printRow(pw, HEAP_FULL_COLUMN, "Dalvik Heap", memInfo.dalvikPss,
1983 memInfo.dalvikSwappablePss, memInfo.dalvikSharedDirty,
1984 memInfo.dalvikPrivateDirty, memInfo.dalvikSharedClean,
1985 memInfo.dalvikPrivateClean, memInfo.dalvikSwappedOut,
1986 dalvikMax, dalvikAllocated, dalvikFree);
1988 printRow(pw, HEAP_COLUMN, "", "Pss", "Private",
1989 "Private", "Swapped", "Heap", "Heap", "Heap");
1990 printRow(pw, HEAP_COLUMN, "", "Total", "Dirty",
1991 "Clean", "Dirty", "Size", "Alloc", "Free");
1992 printRow(pw, HEAP_COLUMN, "", "------", "------", "------",
1993 "------", "------", "------", "------", "------");
1994 printRow(pw, HEAP_COLUMN, "Native Heap", memInfo.nativePss,
1995 memInfo.nativePrivateDirty,
1996 memInfo.nativePrivateClean, memInfo.nativeSwappedOut,
1997 nativeMax, nativeAllocated, nativeFree);
1998 printRow(pw, HEAP_COLUMN, "Dalvik Heap", memInfo.dalvikPss,
1999 memInfo.dalvikPrivateDirty,
2000 memInfo.dalvikPrivateClean, memInfo.dalvikSwappedOut,
2001 dalvikMax, dalvikAllocated, dalvikFree);
2004 int otherPss = memInfo.otherPss;
2005 int otherSwappablePss = memInfo.otherSwappablePss;
2006 int otherSharedDirty = memInfo.otherSharedDirty;
2007 int otherPrivateDirty = memInfo.otherPrivateDirty;
2008 int otherSharedClean = memInfo.otherSharedClean;
2009 int otherPrivateClean = memInfo.otherPrivateClean;
2010 int otherSwappedOut = memInfo.otherSwappedOut;
2012 for (int i=0; i<Debug.MemoryInfo.NUM_OTHER_STATS; i++) {
2013 final int myPss = memInfo.getOtherPss(i);
2014 final int mySwappablePss = memInfo.getOtherSwappablePss(i);
2015 final int mySharedDirty = memInfo.getOtherSharedDirty(i);
2016 final int myPrivateDirty = memInfo.getOtherPrivateDirty(i);
2017 final int mySharedClean = memInfo.getOtherSharedClean(i);
2018 final int myPrivateClean = memInfo.getOtherPrivateClean(i);
2019 final int mySwappedOut = memInfo.getOtherSwappedOut(i);
2020 if (myPss != 0 || mySharedDirty != 0 || myPrivateDirty != 0
2021 || mySharedClean != 0 || myPrivateClean != 0 || mySwappedOut != 0) {
2023 printRow(pw, HEAP_FULL_COLUMN, Debug.MemoryInfo.getOtherLabel(i),
2024 myPss, mySwappablePss, mySharedDirty, myPrivateDirty,
2025 mySharedClean, myPrivateClean, mySwappedOut, "", "", "");
2027 printRow(pw, HEAP_COLUMN, Debug.MemoryInfo.getOtherLabel(i),
2028 myPss, myPrivateDirty,
2029 myPrivateClean, mySwappedOut, "", "", "");
2032 otherSwappablePss -= mySwappablePss;
2033 otherSharedDirty -= mySharedDirty;
2034 otherPrivateDirty -= myPrivateDirty;
2035 otherSharedClean -= mySharedClean;
2036 otherPrivateClean -= myPrivateClean;
2037 otherSwappedOut -= mySwappedOut;
2042 printRow(pw, HEAP_FULL_COLUMN, "Unknown", otherPss, otherSwappablePss,
2043 otherSharedDirty, otherPrivateDirty, otherSharedClean, otherPrivateClean,
2044 otherSwappedOut, "", "", "");
2045 printRow(pw, HEAP_FULL_COLUMN, "TOTAL", memInfo.getTotalPss(),
2046 memInfo.getTotalSwappablePss(),
2047 memInfo.getTotalSharedDirty(), memInfo.getTotalPrivateDirty(),
2048 memInfo.getTotalSharedClean(), memInfo.getTotalPrivateClean(),
2049 memInfo.getTotalSwappedOut(), nativeMax+dalvikMax,
2050 nativeAllocated+dalvikAllocated, nativeFree+dalvikFree);
2052 printRow(pw, HEAP_COLUMN, "Unknown", otherPss,
2053 otherPrivateDirty, otherPrivateClean, otherSwappedOut,
2055 printRow(pw, HEAP_COLUMN, "TOTAL", memInfo.getTotalPss(),
2056 memInfo.getTotalPrivateDirty(),
2057 memInfo.getTotalPrivateClean(),
2058 memInfo.getTotalSwappedOut(),
2059 nativeMax+dalvikMax,
2060 nativeAllocated+dalvikAllocated, nativeFree+dalvikFree);
2065 pw.println(" Dalvik Details");
2067 for (int i=Debug.MemoryInfo.NUM_OTHER_STATS;
2068 i<Debug.MemoryInfo.NUM_OTHER_STATS + Debug.MemoryInfo.NUM_DVK_STATS; i++) {
2069 final int myPss = memInfo.getOtherPss(i);
2070 final int mySwappablePss = memInfo.getOtherSwappablePss(i);
2071 final int mySharedDirty = memInfo.getOtherSharedDirty(i);
2072 final int myPrivateDirty = memInfo.getOtherPrivateDirty(i);
2073 final int mySharedClean = memInfo.getOtherSharedClean(i);
2074 final int myPrivateClean = memInfo.getOtherPrivateClean(i);
2075 final int mySwappedOut = memInfo.getOtherSwappedOut(i);
2076 if (myPss != 0 || mySharedDirty != 0 || myPrivateDirty != 0
2077 || mySharedClean != 0 || myPrivateClean != 0) {
2079 printRow(pw, HEAP_FULL_COLUMN, Debug.MemoryInfo.getOtherLabel(i),
2080 myPss, mySwappablePss, mySharedDirty, myPrivateDirty,
2081 mySharedClean, myPrivateClean, mySwappedOut, "", "", "");
2083 printRow(pw, HEAP_COLUMN, Debug.MemoryInfo.getOtherLabel(i),
2084 myPss, myPrivateDirty,
2085 myPrivateClean, mySwappedOut, "", "", "");
2092 public void registerOnActivityPausedListener(Activity activity,
2093 OnActivityPausedListener listener) {
2094 synchronized (mOnPauseListeners) {
2095 ArrayList<OnActivityPausedListener> list = mOnPauseListeners.get(activity);
2097 list = new ArrayList<OnActivityPausedListener>();
2098 mOnPauseListeners.put(activity, list);
2104 public void unregisterOnActivityPausedListener(Activity activity,
2105 OnActivityPausedListener listener) {
2106 synchronized (mOnPauseListeners) {
2107 ArrayList<OnActivityPausedListener> list = mOnPauseListeners.get(activity);
2109 list.remove(listener);
2114 public final ActivityInfo resolveActivityInfo(Intent intent) {
2115 ActivityInfo aInfo = intent.resolveActivityInfo(
2116 mInitialApplication.getPackageManager(), PackageManager.GET_SHARED_LIBRARY_FILES);
2117 if (aInfo == null) {
2118 // Throw an exception.
2119 Instrumentation.checkStartActivityResult(
2120 ActivityManager.START_CLASS_NOT_FOUND, intent);
2125 public final Activity startActivityNow(Activity parent, String id,
2126 Intent intent, ActivityInfo activityInfo, IBinder token, Bundle state,
2127 Activity.NonConfigurationInstances lastNonConfigurationInstances) {
2128 ActivityClientRecord r = new ActivityClientRecord();
2135 r.activityInfo = activityInfo;
2136 r.lastNonConfigurationInstances = lastNonConfigurationInstances;
2138 ComponentName compname = intent.getComponent();
2140 if (compname != null) {
2141 name = compname.toShortString();
2143 name = "(Intent " + intent + ").getComponent() returned null";
2145 Slog.v(TAG, "Performing launch: action=" + intent.getAction()
2147 + ", token=" + token);
2149 return performLaunchActivity(r, null);
2152 public final Activity getActivity(IBinder token) {
2153 return mActivities.get(token).activity;
2156 public final void sendActivityResult(
2157 IBinder token, String id, int requestCode,
2158 int resultCode, Intent data) {
2159 if (DEBUG_RESULTS) Slog.v(TAG, "sendActivityResult: id=" + id
2160 + " req=" + requestCode + " res=" + resultCode + " data=" + data);
2161 ArrayList<ResultInfo> list = new ArrayList<ResultInfo>();
2162 list.add(new ResultInfo(id, requestCode, resultCode, data));
2163 mAppThread.scheduleSendResult(token, list);
2166 private void sendMessage(int what, Object obj) {
2167 sendMessage(what, obj, 0, 0, false);
2170 private void sendMessage(int what, Object obj, int arg1) {
2171 sendMessage(what, obj, arg1, 0, false);
2174 private void sendMessage(int what, Object obj, int arg1, int arg2) {
2175 sendMessage(what, obj, arg1, arg2, false);
2178 private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
2179 if (DEBUG_MESSAGES) Slog.v(
2180 TAG, "SCHEDULE " + what + " " + mH.codeToString(what)
2181 + ": " + arg1 + " / " + obj);
2182 Message msg = Message.obtain();
2188 msg.setAsynchronous(true);
2190 mH.sendMessage(msg);
2193 final void scheduleContextCleanup(ContextImpl context, String who,
2195 ContextCleanupInfo cci = new ContextCleanupInfo();
2196 cci.context = context;
2199 sendMessage(H.CLEAN_UP_CONTEXT, cci);
2202 private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
2203 // System.out.println("##### [" + System.currentTimeMillis() + "] ActivityThread.performLaunchActivity(" + r + ")");
2205 ActivityInfo aInfo = r.activityInfo;
2206 if (r.packageInfo == null) {
2207 r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
2208 Context.CONTEXT_INCLUDE_CODE);
2211 ComponentName component = r.intent.getComponent();
2212 if (component == null) {
2213 component = r.intent.resolveActivity(
2214 mInitialApplication.getPackageManager());
2215 r.intent.setComponent(component);
2218 if (r.activityInfo.targetActivity != null) {
2219 component = new ComponentName(r.activityInfo.packageName,
2220 r.activityInfo.targetActivity);
2223 Activity activity = null;
2225 java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
2226 activity = mInstrumentation.newActivity(
2227 cl, component.getClassName(), r.intent);
2228 StrictMode.incrementExpectedActivityCount(activity.getClass());
2229 r.intent.setExtrasClassLoader(cl);
2230 r.intent.prepareToEnterProcess();
2231 if (r.state != null) {
2232 r.state.setClassLoader(cl);
2234 } catch (Exception e) {
2235 if (!mInstrumentation.onException(activity, e)) {
2236 throw new RuntimeException(
2237 "Unable to instantiate activity " + component
2238 + ": " + e.toString(), e);
2243 Application app = r.packageInfo.makeApplication(false, mInstrumentation);
2245 if (localLOGV) Slog.v(TAG, "Performing launch of " + r);
2246 if (localLOGV) Slog.v(
2247 TAG, r + ": app=" + app
2248 + ", appName=" + app.getPackageName()
2249 + ", pkg=" + r.packageInfo.getPackageName()
2250 + ", comp=" + r.intent.getComponent().toShortString()
2251 + ", dir=" + r.packageInfo.getAppDir());
2253 if (activity != null) {
2254 Context appContext = createBaseContextForActivity(r, activity);
2255 CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
2256 Configuration config = new Configuration(mCompatConfiguration);
2257 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "
2258 + r.activityInfo.name + " with config " + config);
2259 activity.attach(appContext, this, getInstrumentation(), r.token,
2260 r.ident, app, r.intent, r.activityInfo, title, r.parent,
2261 r.embeddedID, r.lastNonConfigurationInstances, config,
2262 r.referrer, r.voiceInteractor);
2264 if (customIntent != null) {
2265 activity.mIntent = customIntent;
2267 r.lastNonConfigurationInstances = null;
2268 activity.mStartedActivity = false;
2269 int theme = r.activityInfo.getThemeResource();
2271 activity.setTheme(theme);
2274 activity.mCalled = false;
2275 if (r.isPersistable()) {
2276 mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
2278 mInstrumentation.callActivityOnCreate(activity, r.state);
2280 if (!activity.mCalled) {
2281 throw new SuperNotCalledException(
2282 "Activity " + r.intent.getComponent().toShortString() +
2283 " did not call through to super.onCreate()");
2285 r.activity = activity;
2287 if (!r.activity.mFinished) {
2288 activity.performStart();
2291 if (!r.activity.mFinished) {
2292 if (r.isPersistable()) {
2293 if (r.state != null || r.persistentState != null) {
2294 mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state,
2297 } else if (r.state != null) {
2298 mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
2301 if (!r.activity.mFinished) {
2302 activity.mCalled = false;
2303 if (r.isPersistable()) {
2304 mInstrumentation.callActivityOnPostCreate(activity, r.state,
2307 mInstrumentation.callActivityOnPostCreate(activity, r.state);
2309 if (!activity.mCalled) {
2310 throw new SuperNotCalledException(
2311 "Activity " + r.intent.getComponent().toShortString() +
2312 " did not call through to super.onPostCreate()");
2318 mActivities.put(r.token, r);
2320 } catch (SuperNotCalledException e) {
2323 } catch (Exception e) {
2324 if (!mInstrumentation.onException(activity, e)) {
2325 throw new RuntimeException(
2326 "Unable to start activity " + component
2327 + ": " + e.toString(), e);
2334 private Context createBaseContextForActivity(ActivityClientRecord r,
2335 final Activity activity) {
2336 ContextImpl appContext = ContextImpl.createActivityContext(this, r.packageInfo, r.token);
2337 appContext.setOuterContext(activity);
2338 Context baseContext = appContext;
2340 final DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance();
2342 IActivityContainer container =
2343 ActivityManagerNative.getDefault().getEnclosingActivityContainer(r.token);
2344 final int displayId =
2345 container == null ? Display.DEFAULT_DISPLAY : container.getDisplayId();
2346 if (displayId > Display.DEFAULT_DISPLAY) {
2347 Display display = dm.getRealDisplay(displayId, r.token);
2348 baseContext = appContext.createDisplayContext(display);
2350 } catch (RemoteException e) {
2353 // For debugging purposes, if the activity's package name contains the value of
2354 // the "debug.use-second-display" system property as a substring, then show
2355 // its content on a secondary display if there is one.
2356 String pkgName = SystemProperties.get("debug.second-display.pkg");
2357 if (pkgName != null && !pkgName.isEmpty()
2358 && r.packageInfo.mPackageName.contains(pkgName)) {
2359 for (int displayId : dm.getDisplayIds()) {
2360 if (displayId != Display.DEFAULT_DISPLAY) {
2361 Display display = dm.getRealDisplay(displayId, r.token);
2362 baseContext = appContext.createDisplayContext(display);
2370 private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
2371 // If we are getting ready to gc after going to the background, well
2372 // we are back active so skip it.
2373 unscheduleGcIdler();
2374 mSomeActivitiesChanged = true;
2376 if (r.profilerInfo != null) {
2377 mProfiler.setProfiler(r.profilerInfo);
2378 mProfiler.startProfiling();
2381 // Make sure we are running with the most recent config.
2382 handleConfigurationChanged(null, null);
2384 if (localLOGV) Slog.v(
2385 TAG, "Handling launch of " + r);
2387 // Initialize before creating the activity
2388 WindowManagerGlobal.initialize();
2390 Activity a = performLaunchActivity(r, customIntent);
2393 r.createdConfig = new Configuration(mConfiguration);
2394 Bundle oldState = r.state;
2395 handleResumeActivity(r.token, false, r.isForward,
2396 !r.activity.mFinished && !r.startsNotResumed);
2398 if (!r.activity.mFinished && r.startsNotResumed) {
2399 // The activity manager actually wants this one to start out
2400 // paused, because it needs to be visible but isn't in the
2401 // foreground. We accomplish this by going through the
2402 // normal startup (because activities expect to go through
2403 // onResume() the first time they run, before their window
2404 // is displayed), and then pausing it. However, in this case
2405 // we do -not- need to do the full pause cycle (of freezing
2406 // and such) because the activity manager assumes it can just
2407 // retain the current state it has.
2409 r.activity.mCalled = false;
2410 mInstrumentation.callActivityOnPause(r.activity);
2411 // We need to keep around the original state, in case
2412 // we need to be created again. But we only do this
2413 // for pre-Honeycomb apps, which always save their state
2414 // when pausing, so we can not have them save their state
2415 // when restarting from a paused state. For HC and later,
2416 // we want to (and can) let the state be saved as the normal
2417 // part of stopping the activity.
2418 if (r.isPreHoneycomb()) {
2421 if (!r.activity.mCalled) {
2422 throw new SuperNotCalledException(
2423 "Activity " + r.intent.getComponent().toShortString() +
2424 " did not call through to super.onPause()");
2427 } catch (SuperNotCalledException e) {
2430 } catch (Exception e) {
2431 if (!mInstrumentation.onException(r.activity, e)) {
2432 throw new RuntimeException(
2433 "Unable to pause activity "
2434 + r.intent.getComponent().toShortString()
2435 + ": " + e.toString(), e);
2441 // If there was an error, for any reason, tell the activity
2442 // manager to stop us.
2444 ActivityManagerNative.getDefault()
2445 .finishActivity(r.token, Activity.RESULT_CANCELED, null, false);
2446 } catch (RemoteException ex) {
2452 private void deliverNewIntents(ActivityClientRecord r, List<ReferrerIntent> intents) {
2453 final int N = intents.size();
2454 for (int i=0; i<N; i++) {
2455 ReferrerIntent intent = intents.get(i);
2456 intent.setExtrasClassLoader(r.activity.getClassLoader());
2457 intent.prepareToEnterProcess();
2458 r.activity.mFragments.noteStateNotSaved();
2459 mInstrumentation.callActivityOnNewIntent(r.activity, intent);
2463 public final void performNewIntents(IBinder token, List<ReferrerIntent> intents) {
2464 ActivityClientRecord r = mActivities.get(token);
2466 final boolean resumed = !r.paused;
2468 r.activity.mTemporaryPause = true;
2469 mInstrumentation.callActivityOnPause(r.activity);
2471 deliverNewIntents(r, intents);
2473 r.activity.performResume();
2474 r.activity.mTemporaryPause = false;
2479 private void handleNewIntent(NewIntentData data) {
2480 performNewIntents(data.token, data.intents);
2483 public void handleRequestAssistContextExtras(RequestAssistContextExtras cmd) {
2484 Bundle data = new Bundle();
2485 ActivityClientRecord r = mActivities.get(cmd.activityToken);
2487 r.activity.getApplication().dispatchOnProvideAssistData(r.activity, data);
2488 r.activity.onProvideAssistData(data);
2490 if (data.isEmpty()) {
2493 IActivityManager mgr = ActivityManagerNative.getDefault();
2495 mgr.reportAssistContextExtras(cmd.requestToken, data);
2496 } catch (RemoteException e) {
2500 public void handleTranslucentConversionComplete(IBinder token, boolean drawComplete) {
2501 ActivityClientRecord r = mActivities.get(token);
2503 r.activity.onTranslucentConversionComplete(drawComplete);
2507 public void onNewActivityOptions(IBinder token, ActivityOptions options) {
2508 ActivityClientRecord r = mActivities.get(token);
2510 r.activity.onNewActivityOptions(options);
2514 public void handleCancelVisibleBehind(IBinder token) {
2515 ActivityClientRecord r = mActivities.get(token);
2517 mSomeActivitiesChanged = true;
2518 final Activity activity = r.activity;
2519 if (activity.mVisibleBehind) {
2520 activity.mCalled = false;
2521 activity.onVisibleBehindCanceled();
2522 // Tick, tick, tick. The activity has 500 msec to return or it will be destroyed.
2523 if (!activity.mCalled) {
2524 throw new SuperNotCalledException("Activity " + activity.getLocalClassName() +
2525 " did not call through to super.onVisibleBehindCanceled()");
2527 activity.mVisibleBehind = false;
2531 ActivityManagerNative.getDefault().backgroundResourcesReleased(token);
2532 } catch (RemoteException e) {
2536 public void handleOnBackgroundVisibleBehindChanged(IBinder token, boolean visible) {
2537 ActivityClientRecord r = mActivities.get(token);
2539 r.activity.onBackgroundVisibleBehindChanged(visible);
2543 public void handleInstallProvider(ProviderInfo info) {
2544 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
2546 installContentProviders(mInitialApplication, Lists.newArrayList(info));
2548 StrictMode.setThreadPolicy(oldPolicy);
2552 private void handleEnterAnimationComplete(IBinder token) {
2553 ActivityClientRecord r = mActivities.get(token);
2555 r.activity.dispatchEnterAnimationComplete();
2559 private static final ThreadLocal<Intent> sCurrentBroadcastIntent = new ThreadLocal<Intent>();
2562 * Return the Intent that's currently being handled by a
2563 * BroadcastReceiver on this thread, or null if none.
2566 public static Intent getIntentBeingBroadcast() {
2567 return sCurrentBroadcastIntent.get();
2570 private void handleReceiver(ReceiverData data) {
2571 // If we are getting ready to gc after going to the background, well
2572 // we are back active so skip it.
2573 unscheduleGcIdler();
2575 String component = data.intent.getComponent().getClassName();
2577 LoadedApk packageInfo = getPackageInfoNoCheck(
2578 data.info.applicationInfo, data.compatInfo);
2580 IActivityManager mgr = ActivityManagerNative.getDefault();
2582 BroadcastReceiver receiver;
2584 java.lang.ClassLoader cl = packageInfo.getClassLoader();
2585 data.intent.setExtrasClassLoader(cl);
2586 data.intent.prepareToEnterProcess();
2587 data.setExtrasClassLoader(cl);
2588 receiver = (BroadcastReceiver)cl.loadClass(component).newInstance();
2589 } catch (Exception e) {
2590 if (DEBUG_BROADCAST) Slog.i(TAG,
2591 "Finishing failed broadcast to " + data.intent.getComponent());
2592 data.sendFinished(mgr);
2593 throw new RuntimeException(
2594 "Unable to instantiate receiver " + component
2595 + ": " + e.toString(), e);
2599 Application app = packageInfo.makeApplication(false, mInstrumentation);
2601 if (localLOGV) Slog.v(
2602 TAG, "Performing receive of " + data.intent
2604 + ", appName=" + app.getPackageName()
2605 + ", pkg=" + packageInfo.getPackageName()
2606 + ", comp=" + data.intent.getComponent().toShortString()
2607 + ", dir=" + packageInfo.getAppDir());
2609 ContextImpl context = (ContextImpl)app.getBaseContext();
2610 sCurrentBroadcastIntent.set(data.intent);
2611 receiver.setPendingResult(data);
2612 receiver.onReceive(context.getReceiverRestrictedContext(),
2614 } catch (Exception e) {
2615 if (DEBUG_BROADCAST) Slog.i(TAG,
2616 "Finishing failed broadcast to " + data.intent.getComponent());
2617 data.sendFinished(mgr);
2618 if (!mInstrumentation.onException(receiver, e)) {
2619 throw new RuntimeException(
2620 "Unable to start receiver " + component
2621 + ": " + e.toString(), e);
2624 sCurrentBroadcastIntent.set(null);
2627 if (receiver.getPendingResult() != null) {
2632 // Instantiate a BackupAgent and tell it that it's alive
2633 private void handleCreateBackupAgent(CreateBackupAgentData data) {
2634 if (DEBUG_BACKUP) Slog.v(TAG, "handleCreateBackupAgent: " + data);
2636 // Sanity check the requested target package's uid against ours
2638 PackageInfo requestedPackage = getPackageManager().getPackageInfo(
2639 data.appInfo.packageName, 0, UserHandle.myUserId());
2640 if (requestedPackage.applicationInfo.uid != Process.myUid()) {
2641 Slog.w(TAG, "Asked to instantiate non-matching package "
2642 + data.appInfo.packageName);
2645 } catch (RemoteException e) {
2646 Slog.e(TAG, "Can't reach package manager", e);
2650 // no longer idle; we have backup work to do
2651 unscheduleGcIdler();
2653 // instantiate the BackupAgent class named in the manifest
2654 LoadedApk packageInfo = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
2655 String packageName = packageInfo.mPackageName;
2656 if (packageName == null) {
2657 Slog.d(TAG, "Asked to create backup agent for nonexistent package");
2661 String classname = data.appInfo.backupAgentName;
2662 // full backup operation but no app-supplied agent? use the default implementation
2663 if (classname == null && (data.backupMode == IApplicationThread.BACKUP_MODE_FULL
2664 || data.backupMode == IApplicationThread.BACKUP_MODE_RESTORE_FULL)) {
2665 classname = "android.app.backup.FullBackupAgent";
2669 IBinder binder = null;
2670 BackupAgent agent = mBackupAgents.get(packageName);
2671 if (agent != null) {
2672 // reusing the existing instance
2674 Slog.v(TAG, "Reusing existing agent instance");
2676 binder = agent.onBind();
2679 if (DEBUG_BACKUP) Slog.v(TAG, "Initializing agent class " + classname);
2681 java.lang.ClassLoader cl = packageInfo.getClassLoader();
2682 agent = (BackupAgent) cl.loadClass(classname).newInstance();
2684 // set up the agent's context
2685 ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
2686 context.setOuterContext(agent);
2687 agent.attach(context);
2690 binder = agent.onBind();
2691 mBackupAgents.put(packageName, agent);
2692 } catch (Exception e) {
2693 // If this is during restore, fail silently; otherwise go
2694 // ahead and let the user see the crash.
2695 Slog.e(TAG, "Agent threw during creation: " + e);
2696 if (data.backupMode != IApplicationThread.BACKUP_MODE_RESTORE
2697 && data.backupMode != IApplicationThread.BACKUP_MODE_RESTORE_FULL) {
2700 // falling through with 'binder' still null
2704 // tell the OS that we're live now
2706 ActivityManagerNative.getDefault().backupAgentCreated(packageName, binder);
2707 } catch (RemoteException e) {
2710 } catch (Exception e) {
2711 throw new RuntimeException("Unable to create BackupAgent "
2712 + classname + ": " + e.toString(), e);
2716 // Tear down a BackupAgent
2717 private void handleDestroyBackupAgent(CreateBackupAgentData data) {
2718 if (DEBUG_BACKUP) Slog.v(TAG, "handleDestroyBackupAgent: " + data);
2720 LoadedApk packageInfo = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
2721 String packageName = packageInfo.mPackageName;
2722 BackupAgent agent = mBackupAgents.get(packageName);
2723 if (agent != null) {
2726 } catch (Exception e) {
2727 Slog.w(TAG, "Exception thrown in onDestroy by backup agent of " + data.appInfo);
2728 e.printStackTrace();
2730 mBackupAgents.remove(packageName);
2732 Slog.w(TAG, "Attempt to destroy unknown backup agent " + data);
2736 private void handleCreateService(CreateServiceData data) {
2737 // If we are getting ready to gc after going to the background, well
2738 // we are back active so skip it.
2739 unscheduleGcIdler();
2741 LoadedApk packageInfo = getPackageInfoNoCheck(
2742 data.info.applicationInfo, data.compatInfo);
2743 Service service = null;
2745 java.lang.ClassLoader cl = packageInfo.getClassLoader();
2746 service = (Service) cl.loadClass(data.info.name).newInstance();
2747 } catch (Exception e) {
2748 if (!mInstrumentation.onException(service, e)) {
2749 throw new RuntimeException(
2750 "Unable to instantiate service " + data.info.name
2751 + ": " + e.toString(), e);
2756 if (localLOGV) Slog.v(TAG, "Creating service " + data.info.name);
2758 ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
2759 context.setOuterContext(service);
2761 Application app = packageInfo.makeApplication(false, mInstrumentation);
2762 service.attach(context, this, data.info.name, data.token, app,
2763 ActivityManagerNative.getDefault());
2765 mServices.put(data.token, service);
2767 ActivityManagerNative.getDefault().serviceDoneExecuting(
2768 data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
2769 } catch (RemoteException e) {
2772 } catch (Exception e) {
2773 if (!mInstrumentation.onException(service, e)) {
2774 throw new RuntimeException(
2775 "Unable to create service " + data.info.name
2776 + ": " + e.toString(), e);
2781 private void handleBindService(BindServiceData data) {
2782 Service s = mServices.get(data.token);
2784 Slog.v(TAG, "handleBindService s=" + s + " rebind=" + data.rebind);
2787 data.intent.setExtrasClassLoader(s.getClassLoader());
2788 data.intent.prepareToEnterProcess();
2791 IBinder binder = s.onBind(data.intent);
2792 ActivityManagerNative.getDefault().publishService(
2793 data.token, data.intent, binder);
2795 s.onRebind(data.intent);
2796 ActivityManagerNative.getDefault().serviceDoneExecuting(
2797 data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
2800 } catch (RemoteException ex) {
2802 } catch (Exception e) {
2803 if (!mInstrumentation.onException(s, e)) {
2804 throw new RuntimeException(
2805 "Unable to bind to service " + s
2806 + " with " + data.intent + ": " + e.toString(), e);
2812 private void handleUnbindService(BindServiceData data) {
2813 Service s = mServices.get(data.token);
2816 data.intent.setExtrasClassLoader(s.getClassLoader());
2817 data.intent.prepareToEnterProcess();
2818 boolean doRebind = s.onUnbind(data.intent);
2821 ActivityManagerNative.getDefault().unbindFinished(
2822 data.token, data.intent, doRebind);
2824 ActivityManagerNative.getDefault().serviceDoneExecuting(
2825 data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
2827 } catch (RemoteException ex) {
2829 } catch (Exception e) {
2830 if (!mInstrumentation.onException(s, e)) {
2831 throw new RuntimeException(
2832 "Unable to unbind to service " + s
2833 + " with " + data.intent + ": " + e.toString(), e);
2839 private void handleDumpService(DumpComponentInfo info) {
2840 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
2842 Service s = mServices.get(info.token);
2844 PrintWriter pw = new FastPrintWriter(new FileOutputStream(
2845 info.fd.getFileDescriptor()));
2846 s.dump(info.fd.getFileDescriptor(), pw, info.args);
2850 IoUtils.closeQuietly(info.fd);
2851 StrictMode.setThreadPolicy(oldPolicy);
2855 private void handleDumpActivity(DumpComponentInfo info) {
2856 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
2858 ActivityClientRecord r = mActivities.get(info.token);
2859 if (r != null && r.activity != null) {
2860 PrintWriter pw = new FastPrintWriter(new FileOutputStream(
2861 info.fd.getFileDescriptor()));
2862 r.activity.dump(info.prefix, info.fd.getFileDescriptor(), pw, info.args);
2866 IoUtils.closeQuietly(info.fd);
2867 StrictMode.setThreadPolicy(oldPolicy);
2871 private void handleDumpProvider(DumpComponentInfo info) {
2872 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
2874 ProviderClientRecord r = mLocalProviders.get(info.token);
2875 if (r != null && r.mLocalProvider != null) {
2876 PrintWriter pw = new FastPrintWriter(new FileOutputStream(
2877 info.fd.getFileDescriptor()));
2878 r.mLocalProvider.dump(info.fd.getFileDescriptor(), pw, info.args);
2882 IoUtils.closeQuietly(info.fd);
2883 StrictMode.setThreadPolicy(oldPolicy);
2887 private void handleServiceArgs(ServiceArgsData data) {
2888 Service s = mServices.get(data.token);
2891 if (data.args != null) {
2892 data.args.setExtrasClassLoader(s.getClassLoader());
2893 data.args.prepareToEnterProcess();
2896 if (!data.taskRemoved) {
2897 res = s.onStartCommand(data.args, data.flags, data.startId);
2899 s.onTaskRemoved(data.args);
2900 res = Service.START_TASK_REMOVED_COMPLETE;
2903 QueuedWork.waitToFinish();
2906 ActivityManagerNative.getDefault().serviceDoneExecuting(
2907 data.token, SERVICE_DONE_EXECUTING_START, data.startId, res);
2908 } catch (RemoteException e) {
2912 } catch (Exception e) {
2913 if (!mInstrumentation.onException(s, e)) {
2914 throw new RuntimeException(
2915 "Unable to start service " + s
2916 + " with " + data.args + ": " + e.toString(), e);
2922 private void handleStopService(IBinder token) {
2923 Service s = mServices.remove(token);
2926 if (localLOGV) Slog.v(TAG, "Destroying service " + s);
2928 Context context = s.getBaseContext();
2929 if (context instanceof ContextImpl) {
2930 final String who = s.getClassName();
2931 ((ContextImpl) context).scheduleFinalCleanup(who, "Service");
2934 QueuedWork.waitToFinish();
2937 ActivityManagerNative.getDefault().serviceDoneExecuting(
2938 token, SERVICE_DONE_EXECUTING_STOP, 0, 0);
2939 } catch (RemoteException e) {
2941 Slog.i(TAG, "handleStopService: unable to execute serviceDoneExecuting for "
2944 } catch (Exception e) {
2945 if (!mInstrumentation.onException(s, e)) {
2946 throw new RuntimeException(
2947 "Unable to stop service " + s
2948 + ": " + e.toString(), e);
2950 Slog.i(TAG, "handleStopService: exception for " + token, e);
2953 Slog.i(TAG, "handleStopService: token=" + token + " not found.");
2955 //Slog.i(TAG, "Running services: " + mServices);
2958 public final ActivityClientRecord performResumeActivity(IBinder token,
2959 boolean clearHide) {
2960 ActivityClientRecord r = mActivities.get(token);
2961 if (localLOGV) Slog.v(TAG, "Performing resume of " + r
2962 + " finished=" + r.activity.mFinished);
2963 if (r != null && !r.activity.mFinished) {
2965 r.hideForNow = false;
2966 r.activity.mStartedActivity = false;
2969 r.activity.mFragments.noteStateNotSaved();
2970 if (r.pendingIntents != null) {
2971 deliverNewIntents(r, r.pendingIntents);
2972 r.pendingIntents = null;
2974 if (r.pendingResults != null) {
2975 deliverResults(r, r.pendingResults);
2976 r.pendingResults = null;
2978 r.activity.performResume();
2980 EventLog.writeEvent(LOG_ON_RESUME_CALLED,
2981 UserHandle.myUserId(), r.activity.getComponentName().getClassName());
2986 r.persistentState = null;
2987 } catch (Exception e) {
2988 if (!mInstrumentation.onException(r.activity, e)) {
2989 throw new RuntimeException(
2990 "Unable to resume activity "
2991 + r.intent.getComponent().toShortString()
2992 + ": " + e.toString(), e);
2999 static final void cleanUpPendingRemoveWindows(ActivityClientRecord r) {
3000 if (r.mPendingRemoveWindow != null) {
3001 r.mPendingRemoveWindowManager.removeViewImmediate(r.mPendingRemoveWindow);
3002 IBinder wtoken = r.mPendingRemoveWindow.getWindowToken();
3003 if (wtoken != null) {
3004 WindowManagerGlobal.getInstance().closeAll(wtoken,
3005 r.activity.getClass().getName(), "Activity");
3008 r.mPendingRemoveWindow = null;
3009 r.mPendingRemoveWindowManager = null;
3012 final void handleResumeActivity(IBinder token,
3013 boolean clearHide, boolean isForward, boolean reallyResume) {
3014 // If we are getting ready to gc after going to the background, well
3015 // we are back active so skip it.
3016 unscheduleGcIdler();
3017 mSomeActivitiesChanged = true;
3019 // TODO Push resumeArgs into the activity for consideration
3020 ActivityClientRecord r = performResumeActivity(token, clearHide);
3023 final Activity a = r.activity;
3025 if (localLOGV) Slog.v(
3026 TAG, "Resume " + r + " started activity: " +
3027 a.mStartedActivity + ", hideForNow: " + r.hideForNow
3028 + ", finished: " + a.mFinished);
3030 final int forwardBit = isForward ?
3031 WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION : 0;
3033 // If the window hasn't yet been added to the window manager,
3034 // and this guy didn't finish itself or start another activity,
3035 // then go ahead and add the window.
3036 boolean willBeVisible = !a.mStartedActivity;
3037 if (!willBeVisible) {
3039 willBeVisible = ActivityManagerNative.getDefault().willActivityBeVisible(
3040 a.getActivityToken());
3041 } catch (RemoteException e) {
3044 if (r.window == null && !a.mFinished && willBeVisible) {
3045 r.window = r.activity.getWindow();
3046 View decor = r.window.getDecorView();
3047 decor.setVisibility(View.INVISIBLE);
3048 ViewManager wm = a.getWindowManager();
3049 WindowManager.LayoutParams l = r.window.getAttributes();
3051 l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
3052 l.softInputMode |= forwardBit;
3053 if (a.mVisibleFromClient) {
3054 a.mWindowAdded = true;
3055 wm.addView(decor, l);
3058 // If the window has already been added, but during resume
3059 // we started another activity, then don't yet make the
3061 } else if (!willBeVisible) {
3062 if (localLOGV) Slog.v(
3063 TAG, "Launch " + r + " mStartedActivity set");
3064 r.hideForNow = true;
3067 // Get rid of anything left hanging around.
3068 cleanUpPendingRemoveWindows(r);
3070 // The window is now visible if it has been added, we are not
3071 // simply finishing, and we are not starting another activity.
3072 if (!r.activity.mFinished && willBeVisible
3073 && r.activity.mDecor != null && !r.hideForNow) {
3074 if (r.newConfig != null) {
3075 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Resuming activity "
3076 + r.activityInfo.name + " with newConfig " + r.newConfig);
3077 performConfigurationChanged(r.activity, r.newConfig);
3078 freeTextLayoutCachesIfNeeded(r.activity.mCurrentConfig.diff(r.newConfig));
3081 if (localLOGV) Slog.v(TAG, "Resuming " + r + " with isForward="
3083 WindowManager.LayoutParams l = r.window.getAttributes();
3084 if ((l.softInputMode
3085 & WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION)
3087 l.softInputMode = (l.softInputMode
3088 & (~WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION))
3090 if (r.activity.mVisibleFromClient) {
3091 ViewManager wm = a.getWindowManager();
3092 View decor = r.window.getDecorView();
3093 wm.updateViewLayout(decor, l);
3096 r.activity.mVisibleFromServer = true;
3097 mNumVisibleActivities++;
3098 if (r.activity.mVisibleFromClient) {
3099 r.activity.makeVisible();
3103 if (!r.onlyLocalRequest) {
3104 r.nextIdle = mNewActivities;
3106 if (localLOGV) Slog.v(
3107 TAG, "Scheduling idle handler for " + r);
3108 Looper.myQueue().addIdleHandler(new Idler());
3110 r.onlyLocalRequest = false;
3112 // Tell the activity manager we have resumed.
3115 ActivityManagerNative.getDefault().activityResumed(token);
3116 } catch (RemoteException ex) {
3121 // If an exception was thrown when trying to resume, then
3122 // just end this activity.
3124 ActivityManagerNative.getDefault()
3125 .finishActivity(token, Activity.RESULT_CANCELED, null, false);
3126 } catch (RemoteException ex) {
3131 private int mThumbnailWidth = -1;
3132 private int mThumbnailHeight = -1;
3133 private Bitmap mAvailThumbnailBitmap = null;
3134 private Canvas mThumbnailCanvas = null;
3136 private Bitmap createThumbnailBitmap(ActivityClientRecord r) {
3137 Bitmap thumbnail = mAvailThumbnailBitmap;
3139 if (thumbnail == null) {
3140 int w = mThumbnailWidth;
3143 Resources res = r.activity.getResources();
3144 int wId = com.android.internal.R.dimen.thumbnail_width;
3145 int hId = com.android.internal.R.dimen.thumbnail_height;
3146 mThumbnailWidth = w = res.getDimensionPixelSize(wId);
3147 mThumbnailHeight = h = res.getDimensionPixelSize(hId);
3149 h = mThumbnailHeight;
3152 // On platforms where we don't want thumbnails, set dims to (0,0)
3153 if ((w > 0) && (h > 0)) {
3154 thumbnail = Bitmap.createBitmap(r.activity.getResources().getDisplayMetrics(),
3155 w, h, THUMBNAIL_FORMAT);
3156 thumbnail.eraseColor(0);
3160 if (thumbnail != null) {
3161 Canvas cv = mThumbnailCanvas;
3163 mThumbnailCanvas = cv = new Canvas();
3166 cv.setBitmap(thumbnail);
3167 if (!r.activity.onCreateThumbnail(thumbnail, cv)) {
3168 mAvailThumbnailBitmap = thumbnail;
3174 } catch (Exception e) {
3175 if (!mInstrumentation.onException(r.activity, e)) {
3176 throw new RuntimeException(
3177 "Unable to create thumbnail of "
3178 + r.intent.getComponent().toShortString()
3179 + ": " + e.toString(), e);
3187 private void handlePauseActivity(IBinder token, boolean finished,
3188 boolean userLeaving, int configChanges, boolean dontReport) {
3189 ActivityClientRecord r = mActivities.get(token);
3191 //Slog.v(TAG, "userLeaving=" + userLeaving + " handling pause of " + r);
3193 performUserLeavingActivity(r);
3196 r.activity.mConfigChangeFlags |= configChanges;
3197 performPauseActivity(token, finished, r.isPreHoneycomb());
3199 // Make sure any pending writes are now committed.
3200 if (r.isPreHoneycomb()) {
3201 QueuedWork.waitToFinish();
3204 // Tell the activity manager we have paused.
3207 ActivityManagerNative.getDefault().activityPaused(token);
3208 } catch (RemoteException ex) {
3211 mSomeActivitiesChanged = true;
3215 final void performUserLeavingActivity(ActivityClientRecord r) {
3216 mInstrumentation.callActivityOnUserLeaving(r.activity);
3219 final Bundle performPauseActivity(IBinder token, boolean finished,
3220 boolean saveState) {
3221 ActivityClientRecord r = mActivities.get(token);
3222 return r != null ? performPauseActivity(r, finished, saveState) : null;
3225 final Bundle performPauseActivity(ActivityClientRecord r, boolean finished,
3226 boolean saveState) {
3228 if (r.activity.mFinished) {
3229 // If we are finishing, we won't call onResume() in certain cases.
3230 // So here we likewise don't want to call onPause() if the activity
3234 RuntimeException e = new RuntimeException(
3235 "Performing pause of activity that is not resumed: "
3236 + r.intent.getComponent().toShortString());
3237 Slog.e(TAG, e.getMessage(), e);
3240 r.activity.mFinished = true;
3243 // Next have the activity save its current state and managed dialogs...
3244 if (!r.activity.mFinished && saveState) {
3245 callCallActivityOnSaveInstanceState(r);
3248 r.activity.mCalled = false;
3249 mInstrumentation.callActivityOnPause(r.activity);
3250 EventLog.writeEvent(LOG_ON_PAUSE_CALLED, UserHandle.myUserId(),
3251 r.activity.getComponentName().getClassName());
3252 if (!r.activity.mCalled) {
3253 throw new SuperNotCalledException(
3254 "Activity " + r.intent.getComponent().toShortString() +
3255 " did not call through to super.onPause()");
3258 } catch (SuperNotCalledException e) {
3261 } catch (Exception e) {
3262 if (!mInstrumentation.onException(r.activity, e)) {
3263 throw new RuntimeException(
3264 "Unable to pause activity "
3265 + r.intent.getComponent().toShortString()
3266 + ": " + e.toString(), e);
3271 // Notify any outstanding on paused listeners
3272 ArrayList<OnActivityPausedListener> listeners;
3273 synchronized (mOnPauseListeners) {
3274 listeners = mOnPauseListeners.remove(r.activity);
3276 int size = (listeners != null ? listeners.size() : 0);
3277 for (int i = 0; i < size; i++) {
3278 listeners.get(i).onPaused(r.activity);
3281 return !r.activity.mFinished && saveState ? r.state : null;
3284 final void performStopActivity(IBinder token, boolean saveState) {
3285 ActivityClientRecord r = mActivities.get(token);
3286 performStopActivityInner(r, null, false, saveState);
3289 private static class StopInfo implements Runnable {
3290 ActivityClientRecord activity;
3292 PersistableBundle persistentState;
3293 CharSequence description;
3295 @Override public void run() {
3296 // Tell activity manager we have been stopped.
3298 if (DEBUG_MEMORY_TRIM) Slog.v(TAG, "Reporting activity stopped: " + activity);
3299 ActivityManagerNative.getDefault().activityStopped(
3300 activity.token, state, persistentState, description);
3301 } catch (RemoteException ex) {
3306 private static final class ProviderRefCount {
3307 public final IActivityManager.ContentProviderHolder holder;
3308 public final ProviderClientRecord client;
3309 public int stableCount;
3310 public int unstableCount;
3312 // When this is set, the stable and unstable ref counts are 0 and
3313 // we have a pending operation scheduled to remove the ref count
3314 // from the activity manager. On the activity manager we are still
3315 // holding an unstable ref, though it is not reflected in the counts
3317 public boolean removePending;
3319 ProviderRefCount(IActivityManager.ContentProviderHolder inHolder,
3320 ProviderClientRecord inClient, int sCount, int uCount) {
3323 stableCount = sCount;
3324 unstableCount = uCount;
3329 * Core implementation of stopping an activity. Note this is a little
3330 * tricky because the server's meaning of stop is slightly different
3331 * than our client -- for the server, stop means to save state and give
3332 * it the result when it is done, but the window may still be visible.
3333 * For the client, we want to call onStop()/onStart() to indicate when
3334 * the activity's UI visibillity changes.
3336 private void performStopActivityInner(ActivityClientRecord r,
3337 StopInfo info, boolean keepShown, boolean saveState) {
3338 if (localLOGV) Slog.v(TAG, "Performing stop of " + r);
3340 if (!keepShown && r.stopped) {
3341 if (r.activity.mFinished) {
3342 // If we are finishing, we won't call onResume() in certain
3343 // cases. So here we likewise don't want to call onStop()
3344 // if the activity isn't resumed.
3347 RuntimeException e = new RuntimeException(
3348 "Performing stop of activity that is not resumed: "
3349 + r.intent.getComponent().toShortString());
3350 Slog.e(TAG, e.getMessage(), e);
3355 // First create a thumbnail for the activity...
3356 // For now, don't create the thumbnail here; we are
3357 // doing that by doing a screen snapshot.
3358 info.description = r.activity.onCreateDescription();
3359 } catch (Exception e) {
3360 if (!mInstrumentation.onException(r.activity, e)) {
3361 throw new RuntimeException(
3362 "Unable to save state of activity "
3363 + r.intent.getComponent().toShortString()
3364 + ": " + e.toString(), e);
3369 // Next have the activity save its current state and managed dialogs...
3370 if (!r.activity.mFinished && saveState) {
3371 if (r.state == null) {
3372 callCallActivityOnSaveInstanceState(r);
3379 r.activity.performStop();
3380 } catch (Exception e) {
3381 if (!mInstrumentation.onException(r.activity, e)) {
3382 throw new RuntimeException(
3383 "Unable to stop activity "
3384 + r.intent.getComponent().toShortString()
3385 + ": " + e.toString(), e);
3395 private void updateVisibility(ActivityClientRecord r, boolean show) {
3396 View v = r.activity.mDecor;
3399 if (!r.activity.mVisibleFromServer) {
3400 r.activity.mVisibleFromServer = true;
3401 mNumVisibleActivities++;
3402 if (r.activity.mVisibleFromClient) {
3403 r.activity.makeVisible();
3406 if (r.newConfig != null) {
3407 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Updating activity vis "
3408 + r.activityInfo.name + " with new config " + r.newConfig);
3409 performConfigurationChanged(r.activity, r.newConfig);
3410 freeTextLayoutCachesIfNeeded(r.activity.mCurrentConfig.diff(r.newConfig));
3414 if (r.activity.mVisibleFromServer) {
3415 r.activity.mVisibleFromServer = false;
3416 mNumVisibleActivities--;
3417 v.setVisibility(View.INVISIBLE);
3423 private void handleStopActivity(IBinder token, boolean show, int configChanges) {
3424 ActivityClientRecord r = mActivities.get(token);
3425 r.activity.mConfigChangeFlags |= configChanges;
3427 StopInfo info = new StopInfo();
3428 performStopActivityInner(r, info, show, true);
3430 if (localLOGV) Slog.v(
3431 TAG, "Finishing stop of " + r + ": show=" + show
3432 + " win=" + r.window);
3434 updateVisibility(r, show);
3436 // Make sure any pending writes are now committed.
3437 if (!r.isPreHoneycomb()) {
3438 QueuedWork.waitToFinish();
3441 // Schedule the call to tell the activity manager we have
3442 // stopped. We don't do this immediately, because we want to
3443 // have a chance for any other pending work (in particular memory
3444 // trim requests) to complete before you tell the activity
3445 // manager to proceed and allow us to go fully into the background.
3447 info.state = r.state;
3448 info.persistentState = r.persistentState;
3450 mSomeActivitiesChanged = true;
3453 final void performRestartActivity(IBinder token) {
3454 ActivityClientRecord r = mActivities.get(token);
3456 r.activity.performRestart();
3461 private void handleWindowVisibility(IBinder token, boolean show) {
3462 ActivityClientRecord r = mActivities.get(token);
3465 Log.w(TAG, "handleWindowVisibility: no activity for token " + token);
3469 if (!show && !r.stopped) {
3470 performStopActivityInner(r, null, show, false);
3471 } else if (show && r.stopped) {
3472 // If we are getting ready to gc after going to the background, well
3473 // we are back active so skip it.
3474 unscheduleGcIdler();
3476 r.activity.performRestart();
3479 if (r.activity.mDecor != null) {
3481 TAG, "Handle window " + r + " visibility: " + show);
3482 updateVisibility(r, show);
3484 mSomeActivitiesChanged = true;
3487 private void handleSleeping(IBinder token, boolean sleeping) {
3488 ActivityClientRecord r = mActivities.get(token);
3491 Log.w(TAG, "handleSleeping: no activity for token " + token);
3496 if (!r.stopped && !r.isPreHoneycomb()) {
3499 r.activity.performStop();
3500 } catch (Exception e) {
3501 if (!mInstrumentation.onException(r.activity, e)) {
3502 throw new RuntimeException(
3503 "Unable to stop activity "
3504 + r.intent.getComponent().toShortString()
3505 + ": " + e.toString(), e);
3511 // Make sure any pending writes are now committed.
3512 if (!r.isPreHoneycomb()) {
3513 QueuedWork.waitToFinish();
3516 // Tell activity manager we slept.
3518 ActivityManagerNative.getDefault().activitySlept(r.token);
3519 } catch (RemoteException ex) {
3522 if (r.stopped && r.activity.mVisibleFromServer) {
3523 r.activity.performRestart();
3529 private void handleSetCoreSettings(Bundle coreSettings) {
3530 synchronized (mResourcesManager) {
3531 mCoreSettings = coreSettings;
3533 onCoreSettingsChange();
3536 private void onCoreSettingsChange() {
3537 boolean debugViewAttributes =
3538 mCoreSettings.getInt(Settings.Global.DEBUG_VIEW_ATTRIBUTES, 0) != 0;
3539 if (debugViewAttributes != View.mDebugViewAttributes) {
3540 View.mDebugViewAttributes = debugViewAttributes;
3542 // request all activities to relaunch for the changes to take place
3543 for (Map.Entry<IBinder, ActivityClientRecord> entry : mActivities.entrySet()) {
3544 requestRelaunchActivity(entry.getKey(), null, null, 0, false, null, false);
3549 private void handleUpdatePackageCompatibilityInfo(UpdateCompatibilityData data) {
3550 LoadedApk apk = peekPackageInfo(data.pkg, false);
3552 apk.setCompatibilityInfo(data.info);
3554 apk = peekPackageInfo(data.pkg, true);
3556 apk.setCompatibilityInfo(data.info);
3558 handleConfigurationChanged(mConfiguration, data.info);
3559 WindowManagerGlobal.getInstance().reportNewConfiguration(mConfiguration);
3562 private void deliverResults(ActivityClientRecord r, List<ResultInfo> results) {
3563 final int N = results.size();
3564 for (int i=0; i<N; i++) {
3565 ResultInfo ri = results.get(i);
3567 if (ri.mData != null) {
3568 ri.mData.setExtrasClassLoader(r.activity.getClassLoader());
3569 ri.mData.prepareToEnterProcess();
3571 if (DEBUG_RESULTS) Slog.v(TAG,
3572 "Delivering result to activity " + r + " : " + ri);
3573 r.activity.dispatchActivityResult(ri.mResultWho,
3574 ri.mRequestCode, ri.mResultCode, ri.mData);
3575 } catch (Exception e) {
3576 if (!mInstrumentation.onException(r.activity, e)) {
3577 throw new RuntimeException(
3578 "Failure delivering result " + ri + " to activity "
3579 + r.intent.getComponent().toShortString()
3580 + ": " + e.toString(), e);
3586 private void handleSendResult(ResultData res) {
3587 ActivityClientRecord r = mActivities.get(res.token);
3588 if (DEBUG_RESULTS) Slog.v(TAG, "Handling send result to " + r);
3590 final boolean resumed = !r.paused;
3591 if (!r.activity.mFinished && r.activity.mDecor != null
3592 && r.hideForNow && resumed) {
3593 // We had hidden the activity because it started another
3594 // one... we have gotten a result back and we are not
3595 // paused, so make sure our window is visible.
3596 updateVisibility(r, true);
3601 r.activity.mCalled = false;
3602 r.activity.mTemporaryPause = true;
3603 mInstrumentation.callActivityOnPause(r.activity);
3604 if (!r.activity.mCalled) {
3605 throw new SuperNotCalledException(
3606 "Activity " + r.intent.getComponent().toShortString()
3607 + " did not call through to super.onPause()");
3609 } catch (SuperNotCalledException e) {
3611 } catch (Exception e) {
3612 if (!mInstrumentation.onException(r.activity, e)) {
3613 throw new RuntimeException(
3614 "Unable to pause activity "
3615 + r.intent.getComponent().toShortString()
3616 + ": " + e.toString(), e);
3620 deliverResults(r, res.results);
3622 r.activity.performResume();
3623 r.activity.mTemporaryPause = false;
3628 public final ActivityClientRecord performDestroyActivity(IBinder token, boolean finishing) {
3629 return performDestroyActivity(token, finishing, 0, false);
3632 private ActivityClientRecord performDestroyActivity(IBinder token, boolean finishing,
3633 int configChanges, boolean getNonConfigInstance) {
3634 ActivityClientRecord r = mActivities.get(token);
3635 Class<? extends Activity> activityClass = null;
3636 if (localLOGV) Slog.v(TAG, "Performing finish of " + r);
3638 activityClass = r.activity.getClass();
3639 r.activity.mConfigChangeFlags |= configChanges;
3641 r.activity.mFinished = true;
3645 r.activity.mCalled = false;
3646 mInstrumentation.callActivityOnPause(r.activity);
3647 EventLog.writeEvent(LOG_ON_PAUSE_CALLED, UserHandle.myUserId(),
3648 r.activity.getComponentName().getClassName());
3649 if (!r.activity.mCalled) {
3650 throw new SuperNotCalledException(
3651 "Activity " + safeToComponentShortString(r.intent)
3652 + " did not call through to super.onPause()");
3654 } catch (SuperNotCalledException e) {
3656 } catch (Exception e) {
3657 if (!mInstrumentation.onException(r.activity, e)) {
3658 throw new RuntimeException(
3659 "Unable to pause activity "
3660 + safeToComponentShortString(r.intent)
3661 + ": " + e.toString(), e);
3668 r.activity.performStop();
3669 } catch (SuperNotCalledException e) {
3671 } catch (Exception e) {
3672 if (!mInstrumentation.onException(r.activity, e)) {
3673 throw new RuntimeException(
3674 "Unable to stop activity "
3675 + safeToComponentShortString(r.intent)
3676 + ": " + e.toString(), e);
3681 if (getNonConfigInstance) {
3683 r.lastNonConfigurationInstances
3684 = r.activity.retainNonConfigurationInstances();
3685 } catch (Exception e) {
3686 if (!mInstrumentation.onException(r.activity, e)) {
3687 throw new RuntimeException(
3688 "Unable to retain activity "
3689 + r.intent.getComponent().toShortString()
3690 + ": " + e.toString(), e);
3695 r.activity.mCalled = false;
3696 mInstrumentation.callActivityOnDestroy(r.activity);
3697 if (!r.activity.mCalled) {
3698 throw new SuperNotCalledException(
3699 "Activity " + safeToComponentShortString(r.intent) +
3700 " did not call through to super.onDestroy()");
3702 if (r.window != null) {
3703 r.window.closeAllPanels();
3705 } catch (SuperNotCalledException e) {
3707 } catch (Exception e) {
3708 if (!mInstrumentation.onException(r.activity, e)) {
3709 throw new RuntimeException(
3710 "Unable to destroy activity " + safeToComponentShortString(r.intent)
3711 + ": " + e.toString(), e);
3715 mActivities.remove(token);
3716 StrictMode.decrementExpectedActivityCount(activityClass);
3720 private static String safeToComponentShortString(Intent intent) {
3721 ComponentName component = intent.getComponent();
3722 return component == null ? "[Unknown]" : component.toShortString();
3725 private void handleDestroyActivity(IBinder token, boolean finishing,
3726 int configChanges, boolean getNonConfigInstance) {
3727 ActivityClientRecord r = performDestroyActivity(token, finishing,
3728 configChanges, getNonConfigInstance);
3730 cleanUpPendingRemoveWindows(r);
3731 WindowManager wm = r.activity.getWindowManager();
3732 View v = r.activity.mDecor;
3734 if (r.activity.mVisibleFromServer) {
3735 mNumVisibleActivities--;
3737 IBinder wtoken = v.getWindowToken();
3738 if (r.activity.mWindowAdded) {
3739 if (r.onlyLocalRequest) {
3740 // Hold off on removing this until the new activity's
3741 // window is being added.
3742 r.mPendingRemoveWindow = v;
3743 r.mPendingRemoveWindowManager = wm;
3745 wm.removeViewImmediate(v);
3748 if (wtoken != null && r.mPendingRemoveWindow == null) {
3749 WindowManagerGlobal.getInstance().closeAll(wtoken,
3750 r.activity.getClass().getName(), "Activity");
3752 r.activity.mDecor = null;
3754 if (r.mPendingRemoveWindow == null) {
3755 // If we are delaying the removal of the activity window, then
3756 // we can't clean up all windows here. Note that we can't do
3757 // so later either, which means any windows that aren't closed
3758 // by the app will leak. Well we try to warning them a lot
3759 // about leaking windows, because that is a bug, so if they are
3760 // using this recreate facility then they get to live with leaks.
3761 WindowManagerGlobal.getInstance().closeAll(token,
3762 r.activity.getClass().getName(), "Activity");
3765 // Mocked out contexts won't be participating in the normal
3766 // process lifecycle, but if we're running with a proper
3767 // ApplicationContext we need to have it tear down things
3769 Context c = r.activity.getBaseContext();
3770 if (c instanceof ContextImpl) {
3771 ((ContextImpl) c).scheduleFinalCleanup(
3772 r.activity.getClass().getName(), "Activity");
3777 ActivityManagerNative.getDefault().activityDestroyed(token);
3778 } catch (RemoteException ex) {
3779 // If the system process has died, it's game over for everyone.
3782 mSomeActivitiesChanged = true;
3785 public final void requestRelaunchActivity(IBinder token,
3786 List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents,
3787 int configChanges, boolean notResumed, Configuration config,
3788 boolean fromServer) {
3789 ActivityClientRecord target = null;
3791 synchronized (mResourcesManager) {
3792 for (int i=0; i<mRelaunchingActivities.size(); i++) {
3793 ActivityClientRecord r = mRelaunchingActivities.get(i);
3794 if (r.token == token) {
3796 if (pendingResults != null) {
3797 if (r.pendingResults != null) {
3798 r.pendingResults.addAll(pendingResults);
3800 r.pendingResults = pendingResults;
3803 if (pendingNewIntents != null) {
3804 if (r.pendingIntents != null) {
3805 r.pendingIntents.addAll(pendingNewIntents);
3807 r.pendingIntents = pendingNewIntents;
3814 if (target == null) {
3815 target = new ActivityClientRecord();
3816 target.token = token;
3817 target.pendingResults = pendingResults;
3818 target.pendingIntents = pendingNewIntents;
3820 ActivityClientRecord existing = mActivities.get(token);
3821 if (existing != null) {
3822 target.startsNotResumed = existing.paused;
3824 target.onlyLocalRequest = true;
3826 mRelaunchingActivities.add(target);
3827 sendMessage(H.RELAUNCH_ACTIVITY, target);
3831 target.startsNotResumed = notResumed;
3832 target.onlyLocalRequest = false;
3834 if (config != null) {
3835 target.createdConfig = config;
3837 target.pendingConfigChanges |= configChanges;
3841 private void handleRelaunchActivity(ActivityClientRecord tmp) {
3842 // If we are getting ready to gc after going to the background, well
3843 // we are back active so skip it.
3844 unscheduleGcIdler();
3845 mSomeActivitiesChanged = true;
3847 Configuration changedConfig = null;
3848 int configChanges = 0;
3850 // First: make sure we have the most recent configuration and most
3851 // recent version of the activity, or skip it if some previous call
3852 // had taken a more recent version.
3853 synchronized (mResourcesManager) {
3854 int N = mRelaunchingActivities.size();
3855 IBinder token = tmp.token;
3857 for (int i=0; i<N; i++) {
3858 ActivityClientRecord r = mRelaunchingActivities.get(i);
3859 if (r.token == token) {
3861 configChanges |= tmp.pendingConfigChanges;
3862 mRelaunchingActivities.remove(i);
3869 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Abort, activity not relaunching!");
3873 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Relaunching activity "
3874 + tmp.token + " with configChanges=0x"
3875 + Integer.toHexString(configChanges));
3877 if (mPendingConfiguration != null) {
3878 changedConfig = mPendingConfiguration;
3879 mPendingConfiguration = null;
3883 if (tmp.createdConfig != null) {
3884 // If the activity manager is passing us its current config,
3885 // assume that is really what we want regardless of what we
3886 // may have pending.
3887 if (mConfiguration == null
3888 || (tmp.createdConfig.isOtherSeqNewer(mConfiguration)
3889 && mConfiguration.diff(tmp.createdConfig) != 0)) {
3890 if (changedConfig == null
3891 || tmp.createdConfig.isOtherSeqNewer(changedConfig)) {
3892 changedConfig = tmp.createdConfig;
3897 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Relaunching activity "
3898 + tmp.token + ": changedConfig=" + changedConfig);
3900 // If there was a pending configuration change, execute it first.
3901 if (changedConfig != null) {
3902 mCurDefaultDisplayDpi = changedConfig.densityDpi;
3903 updateDefaultDensity();
3904 handleConfigurationChanged(changedConfig, null);
3907 ActivityClientRecord r = mActivities.get(tmp.token);
3908 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handling relaunch of " + r);
3913 r.activity.mConfigChangeFlags |= configChanges;
3914 r.onlyLocalRequest = tmp.onlyLocalRequest;
3915 Intent currentIntent = r.activity.mIntent;
3917 r.activity.mChangingConfigurations = true;
3919 // Need to ensure state is saved.
3921 performPauseActivity(r.token, false, r.isPreHoneycomb());
3923 if (r.state == null && !r.stopped && !r.isPreHoneycomb()) {
3924 callCallActivityOnSaveInstanceState(r);
3927 handleDestroyActivity(r.token, false, configChanges, true);
3931 r.hideForNow = false;
3933 // Merge any pending results and pending intents; don't just replace them
3934 if (tmp.pendingResults != null) {
3935 if (r.pendingResults == null) {
3936 r.pendingResults = tmp.pendingResults;
3938 r.pendingResults.addAll(tmp.pendingResults);
3941 if (tmp.pendingIntents != null) {
3942 if (r.pendingIntents == null) {
3943 r.pendingIntents = tmp.pendingIntents;
3945 r.pendingIntents.addAll(tmp.pendingIntents);
3948 r.startsNotResumed = tmp.startsNotResumed;
3950 handleLaunchActivity(r, currentIntent);
3953 private void callCallActivityOnSaveInstanceState(ActivityClientRecord r) {
3954 r.state = new Bundle();
3955 r.state.setAllowFds(false);
3956 if (r.isPersistable()) {
3957 r.persistentState = new PersistableBundle();
3958 mInstrumentation.callActivityOnSaveInstanceState(r.activity, r.state,
3961 mInstrumentation.callActivityOnSaveInstanceState(r.activity, r.state);
3965 ArrayList<ComponentCallbacks2> collectComponentCallbacks(
3966 boolean allActivities, Configuration newConfig) {
3967 ArrayList<ComponentCallbacks2> callbacks
3968 = new ArrayList<ComponentCallbacks2>();
3970 synchronized (mResourcesManager) {
3971 final int NAPP = mAllApplications.size();
3972 for (int i=0; i<NAPP; i++) {
3973 callbacks.add(mAllApplications.get(i));
3975 final int NACT = mActivities.size();
3976 for (int i=0; i<NACT; i++) {
3977 ActivityClientRecord ar = mActivities.valueAt(i);
3978 Activity a = ar.activity;
3980 Configuration thisConfig = applyConfigCompatMainThread(
3981 mCurDefaultDisplayDpi, newConfig,
3982 ar.packageInfo.getCompatibilityInfo());
3983 if (!ar.activity.mFinished && (allActivities || !ar.paused)) {
3984 // If the activity is currently resumed, its configuration
3985 // needs to change right now.
3987 } else if (thisConfig != null) {
3988 // Otherwise, we will tell it about the change
3989 // the next time it is resumed or shown. Note that
3990 // the activity manager may, before then, decide the
3991 // activity needs to be destroyed to handle its new
3993 if (DEBUG_CONFIGURATION) {
3994 Slog.v(TAG, "Setting activity "
3995 + ar.activityInfo.name + " newConfig=" + thisConfig);
3997 ar.newConfig = thisConfig;
4001 final int NSVC = mServices.size();
4002 for (int i=0; i<NSVC; i++) {
4003 callbacks.add(mServices.valueAt(i));
4006 synchronized (mProviderMap) {
4007 final int NPRV = mLocalProviders.size();
4008 for (int i=0; i<NPRV; i++) {
4009 callbacks.add(mLocalProviders.valueAt(i).mLocalProvider);
4016 private static void performConfigurationChanged(ComponentCallbacks2 cb, Configuration config) {
4017 // Only for Activity objects, check that they actually call up to their
4018 // superclass implementation. ComponentCallbacks2 is an interface, so
4019 // we check the runtime type and act accordingly.
4020 Activity activity = (cb instanceof Activity) ? (Activity) cb : null;
4021 if (activity != null) {
4022 activity.mCalled = false;
4025 boolean shouldChangeConfig = false;
4026 if ((activity == null) || (activity.mCurrentConfig == null)) {
4027 shouldChangeConfig = true;
4030 // If the new config is the same as the config this Activity
4031 // is already running with then don't bother calling
4032 // onConfigurationChanged
4033 int diff = activity.mCurrentConfig.diff(config);
4035 // If this activity doesn't handle any of the config changes
4036 // then don't bother calling onConfigurationChanged as we're
4037 // going to destroy it.
4038 if ((~activity.mActivityInfo.getRealConfigChanged() & diff) == 0) {
4039 shouldChangeConfig = true;
4044 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Config callback " + cb
4045 + ": shouldChangeConfig=" + shouldChangeConfig);
4046 if (shouldChangeConfig) {
4047 cb.onConfigurationChanged(config);
4049 if (activity != null) {
4050 if (!activity.mCalled) {
4051 throw new SuperNotCalledException(
4052 "Activity " + activity.getLocalClassName() +
4053 " did not call through to super.onConfigurationChanged()");
4055 activity.mConfigChangeFlags = 0;
4056 activity.mCurrentConfig = new Configuration(config);
4061 public final void applyConfigurationToResources(Configuration config) {
4062 synchronized (mResourcesManager) {
4063 mResourcesManager.applyConfigurationToResourcesLocked(config, null);
4067 final Configuration applyCompatConfiguration(int displayDensity) {
4068 Configuration config = mConfiguration;
4069 if (mCompatConfiguration == null) {
4070 mCompatConfiguration = new Configuration();
4072 mCompatConfiguration.setTo(mConfiguration);
4073 if (mResourcesManager.applyCompatConfiguration(displayDensity, mCompatConfiguration)) {
4074 config = mCompatConfiguration;
4079 final void handleConfigurationChanged(Configuration config, CompatibilityInfo compat) {
4083 synchronized (mResourcesManager) {
4084 if (mPendingConfiguration != null) {
4085 if (!mPendingConfiguration.isOtherSeqNewer(config)) {
4086 config = mPendingConfiguration;
4087 mCurDefaultDisplayDpi = config.densityDpi;
4088 updateDefaultDensity();
4090 mPendingConfiguration = null;
4093 if (config == null) {
4097 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handle configuration changed: "
4100 mResourcesManager.applyConfigurationToResourcesLocked(config, compat);
4102 if (mConfiguration == null) {
4103 mConfiguration = new Configuration();
4105 if (!mConfiguration.isOtherSeqNewer(config) && compat == null) {
4108 configDiff = mConfiguration.diff(config);
4109 mConfiguration.updateFrom(config);
4110 config = applyCompatConfiguration(mCurDefaultDisplayDpi);
4113 ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(false, config);
4115 freeTextLayoutCachesIfNeeded(configDiff);
4117 if (callbacks != null) {
4118 final int N = callbacks.size();
4119 for (int i=0; i<N; i++) {
4120 performConfigurationChanged(callbacks.get(i), config);
4125 static void freeTextLayoutCachesIfNeeded(int configDiff) {
4126 if (configDiff != 0) {
4127 // Ask text layout engine to free its caches if there is a locale change
4128 boolean hasLocaleConfigChange = ((configDiff & ActivityInfo.CONFIG_LOCALE) != 0);
4129 if (hasLocaleConfigChange) {
4130 Canvas.freeTextLayoutCaches();
4131 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Cleared TextLayout Caches");
4136 final void handleActivityConfigurationChanged(IBinder token) {
4137 ActivityClientRecord r = mActivities.get(token);
4138 if (r == null || r.activity == null) {
4142 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handle activity config changed: "
4143 + r.activityInfo.name);
4145 performConfigurationChanged(r.activity, mCompatConfiguration);
4147 freeTextLayoutCachesIfNeeded(r.activity.mCurrentConfig.diff(mCompatConfiguration));
4149 mSomeActivitiesChanged = true;
4152 final void handleProfilerControl(boolean start, ProfilerInfo profilerInfo, int profileType) {
4155 switch (profileType) {
4157 mProfiler.setProfiler(profilerInfo);
4158 mProfiler.startProfiling();
4161 } catch (RuntimeException e) {
4162 Slog.w(TAG, "Profiling failed on path " + profilerInfo.profileFile
4163 + " -- can the process access this path?");
4166 profilerInfo.profileFd.close();
4167 } catch (IOException e) {
4168 Slog.w(TAG, "Failure closing profile fd", e);
4172 switch (profileType) {
4174 mProfiler.stopProfiling();
4180 static final void handleDumpHeap(boolean managed, DumpHeapData dhd) {
4183 Debug.dumpHprofData(dhd.path, dhd.fd.getFileDescriptor());
4184 } catch (IOException e) {
4185 Slog.w(TAG, "Managed heap dump failed on path " + dhd.path
4186 + " -- can the process access this path?");
4190 } catch (IOException e) {
4191 Slog.w(TAG, "Failure closing profile fd", e);
4195 Debug.dumpNativeHeap(dhd.fd.getFileDescriptor());
4199 final void handleDispatchPackageBroadcast(int cmd, String[] packages) {
4200 boolean hasPkgInfo = false;
4201 if (packages != null) {
4202 for (int i=packages.length-1; i>=0; i--) {
4203 //Slog.i(TAG, "Cleaning old package: " + packages[i]);
4205 WeakReference<LoadedApk> ref;
4206 ref = mPackages.get(packages[i]);
4207 if (ref != null && ref.get() != null) {
4210 ref = mResourcePackages.get(packages[i]);
4211 if (ref != null && ref.get() != null) {
4216 mPackages.remove(packages[i]);
4217 mResourcePackages.remove(packages[i]);
4220 ApplicationPackageManager.handlePackageBroadcast(cmd, packages,
4224 final void handleLowMemory() {
4225 ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(true, null);
4227 final int N = callbacks.size();
4228 for (int i=0; i<N; i++) {
4229 callbacks.get(i).onLowMemory();
4232 // Ask SQLite to free up as much memory as it can, mostly from its page caches.
4233 if (Process.myUid() != Process.SYSTEM_UID) {
4234 int sqliteReleased = SQLiteDatabase.releaseMemory();
4235 EventLog.writeEvent(SQLITE_MEM_RELEASED_EVENT_LOG_TAG, sqliteReleased);
4238 // Ask graphics to free up as much as possible (font/image caches)
4239 Canvas.freeCaches();
4241 // Ask text layout engine to free also as much as possible
4242 Canvas.freeTextLayoutCaches();
4244 BinderInternal.forceGc("mem");
4247 final void handleTrimMemory(int level) {
4248 if (DEBUG_MEMORY_TRIM) Slog.v(TAG, "Trimming memory to level: " + level);
4250 ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(true, null);
4252 final int N = callbacks.size();
4253 for (int i = 0; i < N; i++) {
4254 callbacks.get(i).onTrimMemory(level);
4257 WindowManagerGlobal.getInstance().trimMemory(level);
4260 private void setupGraphicsSupport(LoadedApk info, File cacheDir) {
4261 if (Process.isIsolated()) {
4262 // Isolated processes aren't going to do UI.
4266 int uid = Process.myUid();
4267 String[] packages = getPackageManager().getPackagesForUid(uid);
4269 // If there are several packages in this application we won't
4270 // initialize the graphics disk caches
4271 if (packages != null && packages.length == 1) {
4272 HardwareRenderer.setupDiskCache(cacheDir);
4273 RenderScript.setupDiskCache(cacheDir);
4275 } catch (RemoteException e) {
4280 private void updateDefaultDensity() {
4281 if (mCurDefaultDisplayDpi != Configuration.DENSITY_DPI_UNDEFINED
4282 && mCurDefaultDisplayDpi != DisplayMetrics.DENSITY_DEVICE
4283 && !mDensityCompatMode) {
4284 Slog.i(TAG, "Switching default density from "
4285 + DisplayMetrics.DENSITY_DEVICE + " to "
4286 + mCurDefaultDisplayDpi);
4287 DisplayMetrics.DENSITY_DEVICE = mCurDefaultDisplayDpi;
4288 Bitmap.setDefaultDensity(DisplayMetrics.DENSITY_DEFAULT);
4292 private void handleBindApplication(AppBindData data) {
4293 mBoundApplication = data;
4294 mConfiguration = new Configuration(data.config);
4295 mCompatConfiguration = new Configuration(data.config);
4297 mProfiler = new Profiler();
4298 if (data.initProfilerInfo != null) {
4299 mProfiler.profileFile = data.initProfilerInfo.profileFile;
4300 mProfiler.profileFd = data.initProfilerInfo.profileFd;
4301 mProfiler.samplingInterval = data.initProfilerInfo.samplingInterval;
4302 mProfiler.autoStopProfiler = data.initProfilerInfo.autoStopProfiler;
4305 // send up app name; do this *before* waiting for debugger
4306 Process.setArgV0(data.processName);
4307 android.ddm.DdmHandleAppName.setAppName(data.processName,
4308 UserHandle.myUserId());
4310 if (data.persistent) {
4311 // Persistent processes on low-memory devices do not get to
4312 // use hardware accelerated drawing, since this can add too much
4313 // overhead to the process.
4314 if (!ActivityManager.isHighEndGfx()) {
4315 HardwareRenderer.disable(false);
4319 if (mProfiler.profileFd != null) {
4320 mProfiler.startProfiling();
4323 // If the app is Honeycomb MR1 or earlier, switch its AsyncTask
4324 // implementation to use the pool executor. Normally, we use the
4325 // serialized executor as the default. This has to happen in the
4326 // main thread so the main looper is set right.
4327 if (data.appInfo.targetSdkVersion <= android.os.Build.VERSION_CODES.HONEYCOMB_MR1) {
4328 AsyncTask.setDefaultExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
4331 Message.updateCheckRecycle(data.appInfo.targetSdkVersion);
4334 * Before spawning a new process, reset the time zone to be the system time zone.
4335 * This needs to be done because the system time zone could have changed after the
4336 * the spawning of this process. Without doing this this process would have the incorrect
4339 TimeZone.setDefault(null);
4342 * Initialize the default locale in this process for the reasons we set the time zone.
4344 Locale.setDefault(data.config.locale);
4347 * Update the system configuration since its preloaded and might not
4348 * reflect configuration changes. The configuration object passed
4349 * in AppBindData can be safely assumed to be up to date
4351 mResourcesManager.applyConfigurationToResourcesLocked(data.config, data.compatInfo);
4352 mCurDefaultDisplayDpi = data.config.densityDpi;
4353 applyCompatConfiguration(mCurDefaultDisplayDpi);
4355 data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
4358 * Switch this process to density compatibility mode if needed.
4360 if ((data.appInfo.flags&ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES)
4362 mDensityCompatMode = true;
4363 Bitmap.setDefaultDensity(DisplayMetrics.DENSITY_DEFAULT);
4365 updateDefaultDensity();
4367 final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);
4368 if (!Process.isIsolated()) {
4369 final File cacheDir = appContext.getCacheDir();
4371 if (cacheDir != null) {
4372 // Provide a usable directory for temporary files
4373 System.setProperty("java.io.tmpdir", cacheDir.getAbsolutePath());
4375 setupGraphicsSupport(data.info, cacheDir);
4377 Log.e(TAG, "Unable to setupGraphicsSupport due to missing cache directory");
4382 final boolean is24Hr = "24".equals(mCoreSettings.getString(Settings.System.TIME_12_24));
4383 DateFormat.set24HourTimePref(is24Hr);
4385 View.mDebugViewAttributes =
4386 mCoreSettings.getInt(Settings.Global.DEBUG_VIEW_ATTRIBUTES, 0) != 0;
4389 * For system applications on userdebug/eng builds, log stack
4390 * traces of disk and network access to dropbox for analysis.
4392 if ((data.appInfo.flags &
4393 (ApplicationInfo.FLAG_SYSTEM |
4394 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0) {
4395 StrictMode.conditionallyEnableDebugLogging();
4399 * For apps targetting SDK Honeycomb or later, we don't allow
4400 * network usage on the main event loop / UI thread.
4402 * Note to those grepping: this is what ultimately throws
4403 * NetworkOnMainThreadException ...
4405 if (data.appInfo.targetSdkVersion > 9) {
4406 StrictMode.enableDeathOnNetwork();
4409 if (data.debugMode != IApplicationThread.DEBUG_OFF) {
4410 // XXX should have option to change the port.
4411 Debug.changeDebugPort(8100);
4412 if (data.debugMode == IApplicationThread.DEBUG_WAIT) {
4413 Slog.w(TAG, "Application " + data.info.getPackageName()
4414 + " is waiting for the debugger on port 8100...");
4416 IActivityManager mgr = ActivityManagerNative.getDefault();
4418 mgr.showWaitingForDebugger(mAppThread, true);
4419 } catch (RemoteException ex) {
4422 Debug.waitForDebugger();
4425 mgr.showWaitingForDebugger(mAppThread, false);
4426 } catch (RemoteException ex) {
4430 Slog.w(TAG, "Application " + data.info.getPackageName()
4431 + " can be debugged on port 8100...");
4435 // Enable OpenGL tracing if required
4436 if (data.enableOpenGlTrace) {
4437 GLUtils.setTracingLevel(1);
4440 // Allow application-generated systrace messages if we're debuggable.
4441 boolean appTracingAllowed = (data.appInfo.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0;
4442 Trace.setAppTracingAllowed(appTracingAllowed);
4445 * Initialize the default http proxy in this process for the reasons we set the time zone.
4447 IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE);
4449 // In pre-boot mode (doing initial launch to collect password), not
4450 // all system is up. This includes the connectivity service, so don't
4451 // crash if we can't get it.
4452 IConnectivityManager service = IConnectivityManager.Stub.asInterface(b);
4454 final ProxyInfo proxyInfo = service.getDefaultProxy();
4455 Proxy.setHttpProxySystemProperty(proxyInfo);
4456 } catch (RemoteException e) {}
4459 if (data.instrumentationName != null) {
4460 InstrumentationInfo ii = null;
4462 ii = appContext.getPackageManager().
4463 getInstrumentationInfo(data.instrumentationName, 0);
4464 } catch (PackageManager.NameNotFoundException e) {
4467 throw new RuntimeException(
4468 "Unable to find instrumentation info for: "
4469 + data.instrumentationName);
4472 mInstrumentationPackageName = ii.packageName;
4473 mInstrumentationAppDir = ii.sourceDir;
4474 mInstrumentationSplitAppDirs = ii.splitSourceDirs;
4475 mInstrumentationLibDir = ii.nativeLibraryDir;
4476 mInstrumentedAppDir = data.info.getAppDir();
4477 mInstrumentedSplitAppDirs = data.info.getSplitAppDirs();
4478 mInstrumentedLibDir = data.info.getLibDir();
4480 ApplicationInfo instrApp = new ApplicationInfo();
4481 instrApp.packageName = ii.packageName;
4482 instrApp.sourceDir = ii.sourceDir;
4483 instrApp.publicSourceDir = ii.publicSourceDir;
4484 instrApp.splitSourceDirs = ii.splitSourceDirs;
4485 instrApp.splitPublicSourceDirs = ii.splitPublicSourceDirs;
4486 instrApp.dataDir = ii.dataDir;
4487 instrApp.nativeLibraryDir = ii.nativeLibraryDir;
4488 LoadedApk pi = getPackageInfo(instrApp, data.compatInfo,
4489 appContext.getClassLoader(), false, true, false);
4490 ContextImpl instrContext = ContextImpl.createAppContext(this, pi);
4493 java.lang.ClassLoader cl = instrContext.getClassLoader();
4494 mInstrumentation = (Instrumentation)
4495 cl.loadClass(data.instrumentationName.getClassName()).newInstance();
4496 } catch (Exception e) {
4497 throw new RuntimeException(
4498 "Unable to instantiate instrumentation "
4499 + data.instrumentationName + ": " + e.toString(), e);
4502 mInstrumentation.init(this, instrContext, appContext,
4503 new ComponentName(ii.packageName, ii.name), data.instrumentationWatcher,
4504 data.instrumentationUiAutomationConnection);
4506 if (mProfiler.profileFile != null && !ii.handleProfiling
4507 && mProfiler.profileFd == null) {
4508 mProfiler.handlingProfiling = true;
4509 File file = new File(mProfiler.profileFile);
4510 file.getParentFile().mkdirs();
4511 Debug.startMethodTracing(file.toString(), 8 * 1024 * 1024);
4515 mInstrumentation = new Instrumentation();
4518 if ((data.appInfo.flags&ApplicationInfo.FLAG_LARGE_HEAP) != 0) {
4519 dalvik.system.VMRuntime.getRuntime().clearGrowthLimit();
4522 // Allow disk access during application and provider setup. This could
4523 // block processing ordered broadcasts, but later processing would
4524 // probably end up doing the same disk access.
4525 final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskWrites();
4527 // If the app is being launched for full backup or restore, bring it up in
4528 // a restricted environment with the base application class.
4529 Application app = data.info.makeApplication(data.restrictedBackupMode, null);
4530 mInitialApplication = app;
4532 // don't bring up providers in restricted mode; they may depend on the
4533 // app's custom Application class
4534 if (!data.restrictedBackupMode) {
4535 List<ProviderInfo> providers = data.providers;
4536 if (providers != null) {
4537 installContentProviders(app, providers);
4538 // For process that contains content providers, we want to
4539 // ensure that the JIT is enabled "at some point".
4540 mH.sendEmptyMessageDelayed(H.ENABLE_JIT, 10*1000);
4544 // Do this after providers, since instrumentation tests generally start their
4545 // test thread at this point, and we don't want that racing.
4547 mInstrumentation.onCreate(data.instrumentationArgs);
4549 catch (Exception e) {
4550 throw new RuntimeException(
4551 "Exception thrown in onCreate() of "
4552 + data.instrumentationName + ": " + e.toString(), e);
4556 mInstrumentation.callApplicationOnCreate(app);
4557 } catch (Exception e) {
4558 if (!mInstrumentation.onException(app, e)) {
4559 throw new RuntimeException(
4560 "Unable to create application " + app.getClass().getName()
4561 + ": " + e.toString(), e);
4565 StrictMode.setThreadPolicy(savedPolicy);
4569 /*package*/ final void finishInstrumentation(int resultCode, Bundle results) {
4570 IActivityManager am = ActivityManagerNative.getDefault();
4571 if (mProfiler.profileFile != null && mProfiler.handlingProfiling
4572 && mProfiler.profileFd == null) {
4573 Debug.stopMethodTracing();
4575 //Slog.i(TAG, "am: " + ActivityManagerNative.getDefault()
4576 // + ", app thr: " + mAppThread);
4578 am.finishInstrumentation(mAppThread, resultCode, results);
4579 } catch (RemoteException ex) {
4583 private void installContentProviders(
4584 Context context, List<ProviderInfo> providers) {
4585 final ArrayList<IActivityManager.ContentProviderHolder> results =
4586 new ArrayList<IActivityManager.ContentProviderHolder>();
4588 for (ProviderInfo cpi : providers) {
4589 if (DEBUG_PROVIDER) {
4590 StringBuilder buf = new StringBuilder(128);
4592 buf.append(cpi.authority);
4594 buf.append(cpi.name);
4595 Log.i(TAG, buf.toString());
4597 IActivityManager.ContentProviderHolder cph = installProvider(context, null, cpi,
4598 false /*noisy*/, true /*noReleaseNeeded*/, true /*stable*/);
4600 cph.noReleaseNeeded = true;
4606 ActivityManagerNative.getDefault().publishContentProviders(
4607 getApplicationThread(), results);
4608 } catch (RemoteException ex) {
4612 public final IContentProvider acquireProvider(
4613 Context c, String auth, int userId, boolean stable) {
4614 final IContentProvider provider = acquireExistingProvider(c, auth, userId, stable);
4615 if (provider != null) {
4619 // There is a possible race here. Another thread may try to acquire
4620 // the same provider at the same time. When this happens, we want to ensure
4621 // that the first one wins.
4622 // Note that we cannot hold the lock while acquiring and installing the
4623 // provider since it might take a long time to run and it could also potentially
4624 // be re-entrant in the case where the provider is in the same process.
4625 IActivityManager.ContentProviderHolder holder = null;
4627 holder = ActivityManagerNative.getDefault().getContentProvider(
4628 getApplicationThread(), auth, userId, stable);
4629 } catch (RemoteException ex) {
4631 if (holder == null) {
4632 Slog.e(TAG, "Failed to find provider info for " + auth);
4636 // Install provider will increment the reference count for us, and break
4637 // any ties in the race.
4638 holder = installProvider(c, holder, holder.info,
4639 true /*noisy*/, holder.noReleaseNeeded, stable);
4640 return holder.provider;
4643 private final void incProviderRefLocked(ProviderRefCount prc, boolean stable) {
4645 prc.stableCount += 1;
4646 if (prc.stableCount == 1) {
4647 // We are acquiring a new stable reference on the provider.
4649 if (prc.removePending) {
4650 // We have a pending remove operation, which is holding the
4651 // last unstable reference. At this point we are converting
4652 // that unstable reference to our new stable reference.
4654 // Cancel the removal of the provider.
4655 if (DEBUG_PROVIDER) {
4656 Slog.v(TAG, "incProviderRef: stable "
4657 + "snatched provider from the jaws of death");
4659 prc.removePending = false;
4660 // There is a race! It fails to remove the message, which
4661 // will be handled in completeRemoveProvider().
4662 mH.removeMessages(H.REMOVE_PROVIDER, prc);
4667 if (DEBUG_PROVIDER) {
4668 Slog.v(TAG, "incProviderRef Now stable - "
4669 + prc.holder.info.name + ": unstableDelta="
4672 ActivityManagerNative.getDefault().refContentProvider(
4673 prc.holder.connection, 1, unstableDelta);
4674 } catch (RemoteException e) {
4675 //do nothing content provider object is dead any way
4679 prc.unstableCount += 1;
4680 if (prc.unstableCount == 1) {
4681 // We are acquiring a new unstable reference on the provider.
4682 if (prc.removePending) {
4683 // Oh look, we actually have a remove pending for the
4684 // provider, which is still holding the last unstable
4685 // reference. We just need to cancel that to take new
4686 // ownership of the reference.
4687 if (DEBUG_PROVIDER) {
4688 Slog.v(TAG, "incProviderRef: unstable "
4689 + "snatched provider from the jaws of death");
4691 prc.removePending = false;
4692 mH.removeMessages(H.REMOVE_PROVIDER, prc);
4694 // First unstable ref, increment our count in the
4695 // activity manager.
4697 if (DEBUG_PROVIDER) {
4698 Slog.v(TAG, "incProviderRef: Now unstable - "
4699 + prc.holder.info.name);
4701 ActivityManagerNative.getDefault().refContentProvider(
4702 prc.holder.connection, 0, 1);
4703 } catch (RemoteException e) {
4704 //do nothing content provider object is dead any way
4711 public final IContentProvider acquireExistingProvider(
4712 Context c, String auth, int userId, boolean stable) {
4713 synchronized (mProviderMap) {
4714 final ProviderKey key = new ProviderKey(auth, userId);
4715 final ProviderClientRecord pr = mProviderMap.get(key);
4720 IContentProvider provider = pr.mProvider;
4721 IBinder jBinder = provider.asBinder();
4722 if (!jBinder.isBinderAlive()) {
4723 // The hosting process of the provider has died; we can't
4725 Log.i(TAG, "Acquiring provider " + auth + " for user " + userId
4726 + ": existing object's process dead");
4727 handleUnstableProviderDiedLocked(jBinder, true);
4731 // Only increment the ref count if we have one. If we don't then the
4732 // provider is not reference counted and never needs to be released.
4733 ProviderRefCount prc = mProviderRefCountMap.get(jBinder);
4735 incProviderRefLocked(prc, stable);
4741 public final boolean releaseProvider(IContentProvider provider, boolean stable) {
4742 if (provider == null) {
4746 IBinder jBinder = provider.asBinder();
4747 synchronized (mProviderMap) {
4748 ProviderRefCount prc = mProviderRefCountMap.get(jBinder);
4750 // The provider has no ref count, no release is needed.
4754 boolean lastRef = false;
4756 if (prc.stableCount == 0) {
4757 if (DEBUG_PROVIDER) Slog.v(TAG,
4758 "releaseProvider: stable ref count already 0, how?");
4761 prc.stableCount -= 1;
4762 if (prc.stableCount == 0) {
4763 // What we do at this point depends on whether there are
4764 // any unstable refs left: if there are, we just tell the
4765 // activity manager to decrement its stable count; if there
4766 // aren't, we need to enqueue this provider to be removed,
4767 // and convert to holding a single unstable ref while
4769 lastRef = prc.unstableCount == 0;
4771 if (DEBUG_PROVIDER) {
4772 Slog.v(TAG, "releaseProvider: No longer stable w/lastRef="
4773 + lastRef + " - " + prc.holder.info.name);
4775 ActivityManagerNative.getDefault().refContentProvider(
4776 prc.holder.connection, -1, lastRef ? 1 : 0);
4777 } catch (RemoteException e) {
4778 //do nothing content provider object is dead any way
4782 if (prc.unstableCount == 0) {
4783 if (DEBUG_PROVIDER) Slog.v(TAG,
4784 "releaseProvider: unstable ref count already 0, how?");
4787 prc.unstableCount -= 1;
4788 if (prc.unstableCount == 0) {
4789 // If this is the last reference, we need to enqueue
4790 // this provider to be removed instead of telling the
4791 // activity manager to remove it at this point.
4792 lastRef = prc.stableCount == 0;
4795 if (DEBUG_PROVIDER) {
4796 Slog.v(TAG, "releaseProvider: No longer unstable - "
4797 + prc.holder.info.name);
4799 ActivityManagerNative.getDefault().refContentProvider(
4800 prc.holder.connection, 0, -1);
4801 } catch (RemoteException e) {
4802 //do nothing content provider object is dead any way
4809 if (!prc.removePending) {
4810 // Schedule the actual remove asynchronously, since we don't know the context
4811 // this will be called in.
4812 // TODO: it would be nice to post a delayed message, so
4813 // if we come back and need the same provider quickly
4814 // we will still have it available.
4815 if (DEBUG_PROVIDER) {
4816 Slog.v(TAG, "releaseProvider: Enqueueing pending removal - "
4817 + prc.holder.info.name);
4819 prc.removePending = true;
4820 Message msg = mH.obtainMessage(H.REMOVE_PROVIDER, prc);
4821 mH.sendMessage(msg);
4823 Slog.w(TAG, "Duplicate remove pending of provider " + prc.holder.info.name);
4830 final void completeRemoveProvider(ProviderRefCount prc) {
4831 synchronized (mProviderMap) {
4832 if (!prc.removePending) {
4833 // There was a race! Some other client managed to acquire
4834 // the provider before the removal was completed.
4835 // Abort the removal. We will do it later.
4836 if (DEBUG_PROVIDER) Slog.v(TAG, "completeRemoveProvider: lost the race, "
4837 + "provider still in use");
4841 // More complicated race!! Some client managed to acquire the
4842 // provider and release it before the removal was completed.
4843 // Continue the removal, and abort the next remove message.
4844 prc.removePending = false;
4846 final IBinder jBinder = prc.holder.provider.asBinder();
4847 ProviderRefCount existingPrc = mProviderRefCountMap.get(jBinder);
4848 if (existingPrc == prc) {
4849 mProviderRefCountMap.remove(jBinder);
4852 for (int i=mProviderMap.size()-1; i>=0; i--) {
4853 ProviderClientRecord pr = mProviderMap.valueAt(i);
4854 IBinder myBinder = pr.mProvider.asBinder();
4855 if (myBinder == jBinder) {
4856 mProviderMap.removeAt(i);
4862 if (DEBUG_PROVIDER) {
4863 Slog.v(TAG, "removeProvider: Invoking ActivityManagerNative."
4864 + "removeContentProvider(" + prc.holder.info.name + ")");
4866 ActivityManagerNative.getDefault().removeContentProvider(
4867 prc.holder.connection, false);
4868 } catch (RemoteException e) {
4869 //do nothing content provider object is dead any way
4873 final void handleUnstableProviderDied(IBinder provider, boolean fromClient) {
4874 synchronized (mProviderMap) {
4875 handleUnstableProviderDiedLocked(provider, fromClient);
4879 final void handleUnstableProviderDiedLocked(IBinder provider, boolean fromClient) {
4880 ProviderRefCount prc = mProviderRefCountMap.get(provider);
4882 if (DEBUG_PROVIDER) Slog.v(TAG, "Cleaning up dead provider "
4883 + provider + " " + prc.holder.info.name);
4884 mProviderRefCountMap.remove(provider);
4885 for (int i=mProviderMap.size()-1; i>=0; i--) {
4886 ProviderClientRecord pr = mProviderMap.valueAt(i);
4887 if (pr != null && pr.mProvider.asBinder() == provider) {
4888 Slog.i(TAG, "Removing dead content provider:" + pr.mProvider.toString());
4889 mProviderMap.removeAt(i);
4894 // We found out about this due to execution in our client
4895 // code. Tell the activity manager about it now, to ensure
4896 // that the next time we go to do anything with the provider
4897 // it knows it is dead (so we don't race with its death
4900 ActivityManagerNative.getDefault().unstableProviderDied(
4901 prc.holder.connection);
4902 } catch (RemoteException e) {
4903 //do nothing content provider object is dead any way
4909 final void appNotRespondingViaProvider(IBinder provider) {
4910 synchronized (mProviderMap) {
4911 ProviderRefCount prc = mProviderRefCountMap.get(provider);
4914 ActivityManagerNative.getDefault()
4915 .appNotRespondingViaProvider(prc.holder.connection);
4916 } catch (RemoteException e) {
4922 private ProviderClientRecord installProviderAuthoritiesLocked(IContentProvider provider,
4923 ContentProvider localProvider, IActivityManager.ContentProviderHolder holder) {
4924 final String auths[] = PATTERN_SEMICOLON.split(holder.info.authority);
4925 final int userId = UserHandle.getUserId(holder.info.applicationInfo.uid);
4927 final ProviderClientRecord pcr = new ProviderClientRecord(
4928 auths, provider, localProvider, holder);
4929 for (String auth : auths) {
4930 final ProviderKey key = new ProviderKey(auth, userId);
4931 final ProviderClientRecord existing = mProviderMap.get(key);
4932 if (existing != null) {
4933 Slog.w(TAG, "Content provider " + pcr.mHolder.info.name
4934 + " already published as " + auth);
4936 mProviderMap.put(key, pcr);
4943 * Installs the provider.
4945 * Providers that are local to the process or that come from the system server
4946 * may be installed permanently which is indicated by setting noReleaseNeeded to true.
4947 * Other remote providers are reference counted. The initial reference count
4948 * for all reference counted providers is one. Providers that are not reference
4949 * counted do not have a reference count (at all).
4951 * This method detects when a provider has already been installed. When this happens,
4952 * it increments the reference count of the existing provider (if appropriate)
4953 * and returns the existing provider. This can happen due to concurrent
4954 * attempts to acquire the same provider.
4956 private IActivityManager.ContentProviderHolder installProvider(Context context,
4957 IActivityManager.ContentProviderHolder holder, ProviderInfo info,
4958 boolean noisy, boolean noReleaseNeeded, boolean stable) {
4959 ContentProvider localProvider = null;
4960 IContentProvider provider;
4961 if (holder == null || holder.provider == null) {
4962 if (DEBUG_PROVIDER || noisy) {
4963 Slog.d(TAG, "Loading provider " + info.authority + ": "
4967 ApplicationInfo ai = info.applicationInfo;
4968 if (context.getPackageName().equals(ai.packageName)) {
4970 } else if (mInitialApplication != null &&
4971 mInitialApplication.getPackageName().equals(ai.packageName)) {
4972 c = mInitialApplication;
4975 c = context.createPackageContext(ai.packageName,
4976 Context.CONTEXT_INCLUDE_CODE);
4977 } catch (PackageManager.NameNotFoundException e) {
4982 Slog.w(TAG, "Unable to get context for package " +
4984 " while loading content provider " +
4989 final java.lang.ClassLoader cl = c.getClassLoader();
4990 localProvider = (ContentProvider)cl.
4991 loadClass(info.name).newInstance();
4992 provider = localProvider.getIContentProvider();
4993 if (provider == null) {
4994 Slog.e(TAG, "Failed to instantiate class " +
4995 info.name + " from sourceDir " +
4996 info.applicationInfo.sourceDir);
4999 if (DEBUG_PROVIDER) Slog.v(
5000 TAG, "Instantiating local provider " + info.name);
5001 // XXX Need to create the correct context for this provider.
5002 localProvider.attachInfo(c, info);
5003 } catch (java.lang.Exception e) {
5004 if (!mInstrumentation.onException(null, e)) {
5005 throw new RuntimeException(
5006 "Unable to get provider " + info.name
5007 + ": " + e.toString(), e);
5012 provider = holder.provider;
5013 if (DEBUG_PROVIDER) Slog.v(TAG, "Installing external provider " + info.authority + ": "
5017 IActivityManager.ContentProviderHolder retHolder;
5019 synchronized (mProviderMap) {
5020 if (DEBUG_PROVIDER) Slog.v(TAG, "Checking to add " + provider
5021 + " / " + info.name);
5022 IBinder jBinder = provider.asBinder();
5023 if (localProvider != null) {
5024 ComponentName cname = new ComponentName(info.packageName, info.name);
5025 ProviderClientRecord pr = mLocalProvidersByName.get(cname);
5027 if (DEBUG_PROVIDER) {
5028 Slog.v(TAG, "installProvider: lost the race, "
5029 + "using existing local provider");
5031 provider = pr.mProvider;
5033 holder = new IActivityManager.ContentProviderHolder(info);
5034 holder.provider = provider;
5035 holder.noReleaseNeeded = true;
5036 pr = installProviderAuthoritiesLocked(provider, localProvider, holder);
5037 mLocalProviders.put(jBinder, pr);
5038 mLocalProvidersByName.put(cname, pr);
5040 retHolder = pr.mHolder;
5042 ProviderRefCount prc = mProviderRefCountMap.get(jBinder);
5044 if (DEBUG_PROVIDER) {
5045 Slog.v(TAG, "installProvider: lost the race, updating ref count");
5047 // We need to transfer our new reference to the existing
5048 // ref count, releasing the old one... but only if
5049 // release is needed (that is, it is not running in the
5051 if (!noReleaseNeeded) {
5052 incProviderRefLocked(prc, stable);
5054 ActivityManagerNative.getDefault().removeContentProvider(
5055 holder.connection, stable);
5056 } catch (RemoteException e) {
5057 //do nothing content provider object is dead any way
5061 ProviderClientRecord client = installProviderAuthoritiesLocked(
5062 provider, localProvider, holder);
5063 if (noReleaseNeeded) {
5064 prc = new ProviderRefCount(holder, client, 1000, 1000);
5067 ? new ProviderRefCount(holder, client, 1, 0)
5068 : new ProviderRefCount(holder, client, 0, 1);
5070 mProviderRefCountMap.put(jBinder, prc);
5072 retHolder = prc.holder;
5079 private void attach(boolean system) {
5080 sCurrentActivityThread = this;
5081 mSystemThread = system;
5083 ViewRootImpl.addFirstDrawHandler(new Runnable() {
5089 android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",
5090 UserHandle.myUserId());
5091 RuntimeInit.setApplicationObject(mAppThread.asBinder());
5092 final IActivityManager mgr = ActivityManagerNative.getDefault();
5094 mgr.attachApplication(mAppThread);
5095 } catch (RemoteException ex) {
5098 // Watch for getting close to heap limit.
5099 BinderInternal.addGcWatcher(new Runnable() {
5100 @Override public void run() {
5101 if (!mSomeActivitiesChanged) {
5104 Runtime runtime = Runtime.getRuntime();
5105 long dalvikMax = runtime.maxMemory();
5106 long dalvikUsed = runtime.totalMemory() - runtime.freeMemory();
5107 if (dalvikUsed > ((3*dalvikMax)/4)) {
5108 if (DEBUG_MEMORY_TRIM) Slog.d(TAG, "Dalvik max=" + (dalvikMax/1024)
5109 + " total=" + (runtime.totalMemory()/1024)
5110 + " used=" + (dalvikUsed/1024));
5111 mSomeActivitiesChanged = false;
5113 mgr.releaseSomeActivities(mAppThread);
5114 } catch (RemoteException e) {
5120 // Don't set application object here -- if the system crashes,
5121 // we can't display an alert, we just want to die die die.
5122 android.ddm.DdmHandleAppName.setAppName("system_process",
5123 UserHandle.myUserId());
5125 mInstrumentation = new Instrumentation();
5126 ContextImpl context = ContextImpl.createAppContext(
5127 this, getSystemContext().mPackageInfo);
5128 mInitialApplication = context.mPackageInfo.makeApplication(true, null);
5129 mInitialApplication.onCreate();
5130 } catch (Exception e) {
5131 throw new RuntimeException(
5132 "Unable to instantiate Application():" + e.toString(), e);
5136 // add dropbox logging to libcore
5137 DropBox.setReporter(new DropBoxReporter());
5139 ViewRootImpl.addConfigCallback(new ComponentCallbacks2() {
5141 public void onConfigurationChanged(Configuration newConfig) {
5142 synchronized (mResourcesManager) {
5143 // We need to apply this change to the resources
5144 // immediately, because upon returning the view
5145 // hierarchy will be informed about it.
5146 if (mResourcesManager.applyConfigurationToResourcesLocked(newConfig, null)) {
5147 // This actually changed the resources! Tell
5148 // everyone about it.
5149 if (mPendingConfiguration == null ||
5150 mPendingConfiguration.isOtherSeqNewer(newConfig)) {
5151 mPendingConfiguration = newConfig;
5153 sendMessage(H.CONFIGURATION_CHANGED, newConfig);
5159 public void onLowMemory() {
5162 public void onTrimMemory(int level) {
5167 public static ActivityThread systemMain() {
5168 // The system process on low-memory devices do not get to use hardware
5169 // accelerated drawing, since this can add too much overhead to the
5171 if (!ActivityManager.isHighEndGfx()) {
5172 HardwareRenderer.disable(true);
5174 HardwareRenderer.enableForegroundTrimming();
5176 ActivityThread thread = new ActivityThread();
5177 thread.attach(true);
5181 public final void installSystemProviders(List<ProviderInfo> providers) {
5182 if (providers != null) {
5183 installContentProviders(mInitialApplication, providers);
5187 public int getIntCoreSetting(String key, int defaultValue) {
5188 synchronized (mResourcesManager) {
5189 if (mCoreSettings != null) {
5190 return mCoreSettings.getInt(key, defaultValue);
5192 return defaultValue;
5196 private static class EventLoggingReporter implements EventLogger.Reporter {
5198 public void report (int code, Object... list) {
5199 EventLog.writeEvent(code, list);
5203 private class DropBoxReporter implements DropBox.Reporter {
5205 private DropBoxManager dropBox;
5207 public DropBoxReporter() {
5208 dropBox = (DropBoxManager) getSystemContext().getSystemService(Context.DROPBOX_SERVICE);
5212 public void addData(String tag, byte[] data, int flags) {
5213 dropBox.addData(tag, data, flags);
5217 public void addText(String tag, String data) {
5218 dropBox.addText(tag, data);
5222 public static void main(String[] args) {
5223 SamplingProfilerIntegration.start();
5225 // CloseGuard defaults to true and can be quite spammy. We
5226 // disable it here, but selectively enable it later (via
5227 // StrictMode) on debug builds, but using DropBox, not logs.
5228 CloseGuard.setEnabled(false);
5230 Environment.initForCurrentUser();
5232 // Set the reporter for event logging in libcore
5233 EventLogger.setReporter(new EventLoggingReporter());
5235 Security.addProvider(new AndroidKeyStoreProvider());
5237 // Make sure TrustedCertificateStore looks in the right place for CA certificates
5238 final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
5239 TrustedCertificateStore.setDefaultUserDirectory(configDir);
5241 Process.setArgV0("<pre-initialized>");
5243 Looper.prepareMainLooper();
5245 ActivityThread thread = new ActivityThread();
5246 thread.attach(false);
5248 if (sMainThreadHandler == null) {
5249 sMainThreadHandler = thread.getHandler();
5253 Looper.myLooper().setMessageLogging(new
5254 LogPrinter(Log.DEBUG, "ActivityThread"));
5259 throw new RuntimeException("Main thread loop unexpectedly exited");