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.annotation.NonNull;
20 import android.annotation.Nullable;
21 import android.app.assist.AssistContent;
22 import android.app.assist.AssistStructure;
23 import android.app.backup.BackupAgent;
24 import android.content.BroadcastReceiver;
25 import android.content.ComponentCallbacks2;
26 import android.content.ComponentName;
27 import android.content.ContentProvider;
28 import android.content.Context;
29 import android.content.IContentProvider;
30 import android.content.Intent;
31 import android.content.IIntentReceiver;
32 import android.content.pm.ActivityInfo;
33 import android.content.pm.ApplicationInfo;
34 import android.content.pm.IPackageManager;
35 import android.content.pm.InstrumentationInfo;
36 import android.content.pm.PackageInfo;
37 import android.content.pm.PackageManager;
38 import android.content.pm.PackageManager.NameNotFoundException;
39 import android.content.pm.ProviderInfo;
40 import android.content.pm.ServiceInfo;
41 import android.content.res.AssetManager;
42 import android.content.res.CompatibilityInfo;
43 import android.content.res.Configuration;
44 import android.content.res.Resources;
45 import android.content.res.Resources.Theme;
46 import android.database.sqlite.SQLiteDatabase;
47 import android.database.sqlite.SQLiteDebug;
48 import android.database.sqlite.SQLiteDebug.DbStats;
49 import android.graphics.Bitmap;
50 import android.graphics.Canvas;
51 import android.hardware.display.DisplayManagerGlobal;
52 import android.net.ConnectivityManager;
53 import android.net.IConnectivityManager;
54 import android.net.Network;
55 import android.net.Proxy;
56 import android.net.ProxyInfo;
57 import android.net.Uri;
58 import android.os.AsyncTask;
59 import android.os.Binder;
60 import android.os.Build;
61 import android.os.Bundle;
62 import android.os.Debug;
63 import android.os.DropBoxManager;
64 import android.os.Environment;
65 import android.os.Handler;
66 import android.os.IBinder;
67 import android.os.LocaleList;
68 import android.os.Looper;
69 import android.os.Message;
70 import android.os.MessageQueue;
71 import android.os.Parcel;
72 import android.os.ParcelFileDescriptor;
73 import android.os.PersistableBundle;
74 import android.os.Process;
75 import android.os.RemoteException;
76 import android.os.ServiceManager;
77 import android.os.StrictMode;
78 import android.os.SystemClock;
79 import android.os.SystemProperties;
80 import android.os.Trace;
81 import android.os.TransactionTooLargeException;
82 import android.os.UserHandle;
83 import android.provider.Settings;
84 import android.security.NetworkSecurityPolicy;
85 import android.security.net.config.NetworkSecurityConfigProvider;
86 import android.util.AndroidRuntimeException;
87 import android.util.ArrayMap;
88 import android.util.DisplayMetrics;
89 import android.util.EventLog;
90 import android.util.Log;
91 import android.util.LogPrinter;
92 import android.util.Pair;
93 import android.util.PrintWriterPrinter;
94 import android.util.Slog;
95 import android.util.SparseIntArray;
96 import android.util.SuperNotCalledException;
97 import android.view.ContextThemeWrapper;
98 import android.view.Display;
99 import android.view.ThreadedRenderer;
100 import android.view.View;
101 import android.view.ViewDebug;
102 import android.view.ViewManager;
103 import android.view.ViewRootImpl;
104 import android.view.Window;
105 import android.view.WindowManager;
106 import android.view.WindowManagerGlobal;
107 import android.renderscript.RenderScriptCacheDir;
108 import android.system.Os;
109 import android.system.OsConstants;
110 import android.system.ErrnoException;
112 import com.android.internal.annotations.GuardedBy;
113 import com.android.internal.app.IVoiceInteractor;
114 import com.android.internal.content.ReferrerIntent;
115 import com.android.internal.os.BinderInternal;
116 import com.android.internal.os.RuntimeInit;
117 import com.android.internal.os.SamplingProfilerIntegration;
118 import com.android.internal.os.SomeArgs;
119 import com.android.internal.util.ArrayUtils;
120 import com.android.internal.util.FastPrintWriter;
121 import com.android.org.conscrypt.OpenSSLSocketImpl;
122 import com.android.org.conscrypt.TrustedCertificateStore;
123 import com.google.android.collect.Lists;
126 import java.io.FileDescriptor;
127 import java.io.FileOutputStream;
128 import java.io.IOException;
129 import java.io.PrintWriter;
130 import java.lang.ref.WeakReference;
131 import java.net.InetAddress;
132 import java.text.DateFormat;
133 import java.util.ArrayList;
134 import java.util.Collections;
135 import java.util.List;
136 import java.util.Locale;
137 import java.util.Map;
138 import java.util.Objects;
139 import java.util.TimeZone;
141 import libcore.io.DropBox;
142 import libcore.io.EventLogger;
143 import libcore.io.IoUtils;
144 import libcore.net.event.NetworkEventDispatcher;
145 import dalvik.system.CloseGuard;
146 import dalvik.system.VMDebug;
147 import dalvik.system.VMRuntime;
148 import org.apache.harmony.dalvik.ddmc.DdmVmInternal;
150 final class RemoteServiceException extends AndroidRuntimeException {
151 public RemoteServiceException(String msg) {
157 * This manages the execution of the main thread in an
158 * application process, scheduling and executing activities,
159 * broadcasts, and other operations on it as the activity
164 public final class ActivityThread {
166 public static final String TAG = "ActivityThread";
167 private static final android.graphics.Bitmap.Config THUMBNAIL_FORMAT = Bitmap.Config.RGB_565;
168 static final boolean localLOGV = false;
169 static final boolean DEBUG_MESSAGES = false;
171 public static final boolean DEBUG_BROADCAST = false;
172 private static final boolean DEBUG_RESULTS = false;
173 private static final boolean DEBUG_BACKUP = false;
174 public static final boolean DEBUG_CONFIGURATION = false;
175 private static final boolean DEBUG_SERVICE = false;
176 private static final boolean DEBUG_MEMORY_TRIM = false;
177 private static final boolean DEBUG_PROVIDER = false;
178 private static final boolean DEBUG_ORDER = false;
179 private static final long MIN_TIME_BETWEEN_GCS = 5*1000;
180 private static final int SQLITE_MEM_RELEASED_EVENT_LOG_TAG = 75003;
181 private static final int LOG_AM_ON_PAUSE_CALLED = 30021;
182 private static final int LOG_AM_ON_RESUME_CALLED = 30022;
183 private static final int LOG_AM_ON_STOP_CALLED = 30049;
185 /** Type for IActivityManager.serviceDoneExecuting: anonymous operation */
186 public static final int SERVICE_DONE_EXECUTING_ANON = 0;
187 /** Type for IActivityManager.serviceDoneExecuting: done with an onStart call */
188 public static final int SERVICE_DONE_EXECUTING_START = 1;
189 /** Type for IActivityManager.serviceDoneExecuting: done stopping (destroying) service */
190 public static final int SERVICE_DONE_EXECUTING_STOP = 2;
192 // Details for pausing activity.
193 private static final int USER_LEAVING = 1;
194 private static final int DONT_REPORT = 2;
196 // Whether to invoke an activity callback after delivering new configuration.
197 private static final boolean REPORT_TO_ACTIVITY = true;
199 private ContextImpl mSystemContext;
201 static volatile IPackageManager sPackageManager;
203 final ApplicationThread mAppThread = new ApplicationThread();
204 final Looper mLooper = Looper.myLooper();
205 final H mH = new H();
206 final ArrayMap<IBinder, ActivityClientRecord> mActivities = new ArrayMap<>();
207 // List of new activities (via ActivityRecord.nextIdle) that should
208 // be reported when next we idle.
209 ActivityClientRecord mNewActivities = null;
210 // Number of activities that are currently visible on-screen.
211 int mNumVisibleActivities = 0;
212 ArrayList<WeakReference<AssistStructure>> mLastAssistStructures = new ArrayList<>();
213 private int mLastSessionId;
214 final ArrayMap<IBinder, Service> mServices = new ArrayMap<>();
215 AppBindData mBoundApplication;
217 int mCurDefaultDisplayDpi;
218 boolean mDensityCompatMode;
219 Configuration mConfiguration;
220 Configuration mCompatConfiguration;
221 Application mInitialApplication;
222 final ArrayList<Application> mAllApplications
223 = new ArrayList<Application>();
224 // set of instantiated backup agents, keyed by package name
225 final ArrayMap<String, BackupAgent> mBackupAgents = new ArrayMap<String, BackupAgent>();
226 /** Reference to singleton {@link ActivityThread} */
227 private static volatile ActivityThread sCurrentActivityThread;
228 Instrumentation mInstrumentation;
229 String mInstrumentationPackageName = null;
230 String mInstrumentationAppDir = null;
231 String[] mInstrumentationSplitAppDirs = null;
232 String mInstrumentationLibDir = null;
233 String mInstrumentedAppDir = null;
234 String[] mInstrumentedSplitAppDirs = null;
235 String mInstrumentedLibDir = null;
236 boolean mSystemThread = false;
237 boolean mJitEnabled = false;
238 boolean mSomeActivitiesChanged = false;
240 // These can be accessed by multiple threads; mPackages is the lock.
241 // XXX For now we keep around information about all packages we have
242 // seen, not removing entries from this map.
243 // NOTE: The activity and window managers need to call in to
244 // ActivityThread to do things like update resource configurations,
245 // which means this lock gets held while the activity and window managers
246 // holds their own lock. Thus you MUST NEVER call back into the activity manager
247 // or window manager or anything that depends on them while holding this lock.
248 // These LoadedApk are only valid for the userId that we're running as.
249 final ArrayMap<String, WeakReference<LoadedApk>> mPackages
250 = new ArrayMap<String, WeakReference<LoadedApk>>();
251 final ArrayMap<String, WeakReference<LoadedApk>> mResourcePackages
252 = new ArrayMap<String, WeakReference<LoadedApk>>();
253 final ArrayList<ActivityClientRecord> mRelaunchingActivities
254 = new ArrayList<ActivityClientRecord>();
255 Configuration mPendingConfiguration = null;
256 // Because we merge activity relaunch operations we can't depend on the ordering provided by
257 // the handler messages. We need to introduce secondary ordering mechanism, which will allow
258 // us to drop certain events, if we know that they happened before relaunch we already executed.
259 // This represents the order of receiving the request from AM.
260 @GuardedBy("mResourcesManager")
261 int mLifecycleSeq = 0;
263 private final ResourcesManager mResourcesManager;
265 private static final class ProviderKey {
266 final String authority;
269 public ProviderKey(String authority, int userId) {
270 this.authority = authority;
271 this.userId = userId;
275 public boolean equals(Object o) {
276 if (o instanceof ProviderKey) {
277 final ProviderKey other = (ProviderKey) o;
278 return Objects.equals(authority, other.authority) && userId == other.userId;
284 public int hashCode() {
285 return ((authority != null) ? authority.hashCode() : 0) ^ userId;
289 // The lock of mProviderMap protects the following variables.
290 final ArrayMap<ProviderKey, ProviderClientRecord> mProviderMap
291 = new ArrayMap<ProviderKey, ProviderClientRecord>();
292 final ArrayMap<IBinder, ProviderRefCount> mProviderRefCountMap
293 = new ArrayMap<IBinder, ProviderRefCount>();
294 final ArrayMap<IBinder, ProviderClientRecord> mLocalProviders
295 = new ArrayMap<IBinder, ProviderClientRecord>();
296 final ArrayMap<ComponentName, ProviderClientRecord> mLocalProvidersByName
297 = new ArrayMap<ComponentName, ProviderClientRecord>();
299 final ArrayMap<Activity, ArrayList<OnActivityPausedListener>> mOnPauseListeners
300 = new ArrayMap<Activity, ArrayList<OnActivityPausedListener>>();
302 final GcIdler mGcIdler = new GcIdler();
303 boolean mGcIdlerScheduled = false;
305 static volatile Handler sMainThreadHandler; // set once in main()
307 Bundle mCoreSettings = null;
309 static final class ActivityClientRecord {
314 IVoiceInteractor voiceInteractor;
316 PersistableBundle persistentState;
321 Activity.NonConfigurationInstances lastNonConfigurationInstances;
325 Configuration newConfig;
326 Configuration createdConfig;
327 Configuration overrideConfig;
328 // Used for consolidating configs before sending on to Activity.
329 private Configuration tmpConfig = new Configuration();
330 ActivityClientRecord nextIdle;
332 ProfilerInfo profilerInfo;
334 ActivityInfo activityInfo;
335 CompatibilityInfo compatInfo;
336 LoadedApk packageInfo;
338 List<ResultInfo> pendingResults;
339 List<ReferrerIntent> pendingIntents;
341 boolean startsNotResumed;
343 int pendingConfigChanges;
344 boolean onlyLocalRequest;
346 Window mPendingRemoveWindow;
347 WindowManager mPendingRemoveWindowManager;
348 boolean mPreserveWindow;
350 // Set for relaunch requests, indicates the order number of the relaunch operation, so it
351 // can be compared with other lifecycle operations.
354 // Can only be accessed from the UI thread. This represents the latest processed message
355 // that is related to lifecycle events/
356 int lastProcessedSeq = 0;
358 ActivityClientRecord() {
367 public boolean isPreHoneycomb() {
368 if (activity != null) {
369 return activity.getApplicationInfo().targetSdkVersion
370 < android.os.Build.VERSION_CODES.HONEYCOMB;
375 public boolean isPersistable() {
376 return activityInfo.persistableMode == ActivityInfo.PERSIST_ACROSS_REBOOTS;
379 public String toString() {
380 ComponentName componentName = intent != null ? intent.getComponent() : null;
381 return "ActivityRecord{"
382 + Integer.toHexString(System.identityHashCode(this))
383 + " token=" + token + " " + (componentName == null
384 ? "no component name" : componentName.toShortString())
388 public String getStateString() {
389 StringBuilder sb = new StringBuilder();
390 sb.append("ActivityClientRecord{");
391 sb.append("paused=").append(paused);
392 sb.append(", stopped=").append(stopped);
393 sb.append(", hideForNow=").append(hideForNow);
394 sb.append(", startsNotResumed=").append(startsNotResumed);
395 sb.append(", isForward=").append(isForward);
396 sb.append(", pendingConfigChanges=").append(pendingConfigChanges);
397 sb.append(", onlyLocalRequest=").append(onlyLocalRequest);
398 sb.append(", preserveWindow=").append(mPreserveWindow);
399 if (activity != null) {
400 sb.append(", Activity{");
401 sb.append("resumed=").append(activity.mResumed);
402 sb.append(", stopped=").append(activity.mStopped);
403 sb.append(", finished=").append(activity.isFinishing());
404 sb.append(", destroyed=").append(activity.isDestroyed());
405 sb.append(", startedActivity=").append(activity.mStartedActivity);
406 sb.append(", temporaryPause=").append(activity.mTemporaryPause);
407 sb.append(", changingConfigurations=").append(activity.mChangingConfigurations);
408 sb.append(", visibleBehind=").append(activity.mVisibleBehind);
412 return sb.toString();
416 final class ProviderClientRecord {
417 final String[] mNames;
418 final IContentProvider mProvider;
419 final ContentProvider mLocalProvider;
420 final IActivityManager.ContentProviderHolder mHolder;
422 ProviderClientRecord(String[] names, IContentProvider provider,
423 ContentProvider localProvider,
424 IActivityManager.ContentProviderHolder holder) {
426 mProvider = provider;
427 mLocalProvider = localProvider;
432 static final class NewIntentData {
433 List<ReferrerIntent> intents;
435 public String toString() {
436 return "NewIntentData{intents=" + intents + " token=" + token + "}";
440 static final class ReceiverData extends BroadcastReceiver.PendingResult {
441 public ReceiverData(Intent intent, int resultCode, String resultData, Bundle resultExtras,
442 boolean ordered, boolean sticky, IBinder token, int sendingUser) {
443 super(resultCode, resultData, resultExtras, TYPE_COMPONENT, ordered, sticky,
444 token, sendingUser, intent.getFlags());
445 this.intent = intent;
450 CompatibilityInfo compatInfo;
451 public String toString() {
452 return "ReceiverData{intent=" + intent + " packageName=" +
453 info.packageName + " resultCode=" + getResultCode()
454 + " resultData=" + getResultData() + " resultExtras="
455 + getResultExtras(false) + "}";
459 static final class CreateBackupAgentData {
460 ApplicationInfo appInfo;
461 CompatibilityInfo compatInfo;
463 public String toString() {
464 return "CreateBackupAgentData{appInfo=" + appInfo
465 + " backupAgent=" + appInfo.backupAgentName
466 + " mode=" + backupMode + "}";
470 static final class CreateServiceData {
473 CompatibilityInfo compatInfo;
475 public String toString() {
476 return "CreateServiceData{token=" + token + " className="
477 + info.name + " packageName=" + info.packageName
478 + " intent=" + intent + "}";
482 static final class BindServiceData {
486 public String toString() {
487 return "BindServiceData{token=" + token + " intent=" + intent + "}";
491 static final class ServiceArgsData {
497 public String toString() {
498 return "ServiceArgsData{token=" + token + " startId=" + startId
499 + " args=" + args + "}";
503 static final class AppBindData {
506 ApplicationInfo appInfo;
507 List<ProviderInfo> providers;
508 ComponentName instrumentationName;
509 Bundle instrumentationArgs;
510 IInstrumentationWatcher instrumentationWatcher;
511 IUiAutomationConnection instrumentationUiAutomationConnection;
513 boolean enableBinderTracking;
514 boolean trackAllocation;
515 boolean restrictedBackupMode;
517 Configuration config;
518 CompatibilityInfo compatInfo;
520 /** Initial values for {@link Profiler}. */
521 ProfilerInfo initProfilerInfo;
523 public String toString() {
524 return "AppBindData{appInfo=" + appInfo + "}";
528 static final class Profiler {
530 ParcelFileDescriptor profileFd;
531 int samplingInterval;
532 boolean autoStopProfiler;
534 boolean handlingProfiling;
535 public void setProfiler(ProfilerInfo profilerInfo) {
536 ParcelFileDescriptor fd = profilerInfo.profileFd;
541 } catch (IOException e) {
547 if (profileFd != null) {
550 } catch (IOException e) {
554 profileFile = profilerInfo.profileFile;
556 samplingInterval = profilerInfo.samplingInterval;
557 autoStopProfiler = profilerInfo.autoStopProfiler;
559 public void startProfiling() {
560 if (profileFd == null || profiling) {
564 int bufferSize = SystemProperties.getInt("debug.traceview-buffer-size-mb", 8);
565 VMDebug.startMethodTracing(profileFile, profileFd.getFileDescriptor(),
566 bufferSize * 1024 * 1024, 0, samplingInterval != 0, samplingInterval);
568 } catch (RuntimeException e) {
569 Slog.w(TAG, "Profiling failed on path " + profileFile);
573 } catch (IOException e2) {
574 Slog.w(TAG, "Failure closing profile fd", e2);
578 public void stopProfiling() {
581 Debug.stopMethodTracing();
582 if (profileFd != null) {
585 } catch (IOException e) {
594 static final class DumpComponentInfo {
595 ParcelFileDescriptor fd;
601 static final class ResultData {
603 List<ResultInfo> results;
604 public String toString() {
605 return "ResultData{token=" + token + " results" + results + "}";
609 static final class ContextCleanupInfo {
615 static final class DumpHeapData {
617 ParcelFileDescriptor fd;
620 static final class UpdateCompatibilityData {
622 CompatibilityInfo info;
625 static final class RequestAssistContextExtras {
626 IBinder activityToken;
627 IBinder requestToken;
632 static final class ActivityConfigChangeData {
633 final IBinder activityToken;
634 final Configuration overrideConfig;
635 public ActivityConfigChangeData(IBinder token, Configuration config) {
636 activityToken = token;
637 overrideConfig = config;
641 private native void dumpGraphicsInfo(FileDescriptor fd);
643 private class ApplicationThread extends ApplicationThreadNative {
644 private static final String DB_INFO_FORMAT = " %8s %8s %14s %14s %s";
646 private int mLastProcessState = -1;
648 private void updatePendingConfiguration(Configuration config) {
649 synchronized (mResourcesManager) {
650 if (mPendingConfiguration == null ||
651 mPendingConfiguration.isOtherSeqNewer(config)) {
652 mPendingConfiguration = config;
657 public final void schedulePauseActivity(IBinder token, boolean finished,
658 boolean userLeaving, int configChanges, boolean dontReport) {
659 int seq = getLifecycleSeq();
660 if (DEBUG_ORDER) Slog.d(TAG, "pauseActivity " + ActivityThread.this
661 + " operation received seq: " + seq);
663 finished ? H.PAUSE_ACTIVITY_FINISHING : H.PAUSE_ACTIVITY,
665 (userLeaving ? USER_LEAVING : 0) | (dontReport ? DONT_REPORT : 0),
670 public final void scheduleStopActivity(IBinder token, boolean showWindow,
672 int seq = getLifecycleSeq();
673 if (DEBUG_ORDER) Slog.d(TAG, "stopActivity " + ActivityThread.this
674 + " operation received seq: " + seq);
676 showWindow ? H.STOP_ACTIVITY_SHOW : H.STOP_ACTIVITY_HIDE,
677 token, 0, configChanges, seq);
680 public final void scheduleWindowVisibility(IBinder token, boolean showWindow) {
682 showWindow ? H.SHOW_WINDOW : H.HIDE_WINDOW,
686 public final void scheduleSleeping(IBinder token, boolean sleeping) {
687 sendMessage(H.SLEEPING, token, sleeping ? 1 : 0);
690 public final void scheduleResumeActivity(IBinder token, int processState,
691 boolean isForward, Bundle resumeArgs) {
692 int seq = getLifecycleSeq();
693 if (DEBUG_ORDER) Slog.d(TAG, "resumeActivity " + ActivityThread.this
694 + " operation received seq: " + seq);
695 updateProcessState(processState, false);
696 sendMessage(H.RESUME_ACTIVITY, token, isForward ? 1 : 0, 0, seq);
699 public final void scheduleSendResult(IBinder token, List<ResultInfo> results) {
700 ResultData res = new ResultData();
702 res.results = results;
703 sendMessage(H.SEND_RESULT, res);
706 // we use token to identify this activity without having to send the
707 // activity itself back to the activity manager. (matters more with ipc)
709 public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
710 ActivityInfo info, Configuration curConfig, Configuration overrideConfig,
711 CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor,
712 int procState, Bundle state, PersistableBundle persistentState,
713 List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents,
714 boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) {
716 updateProcessState(procState, false);
718 ActivityClientRecord r = new ActivityClientRecord();
723 r.referrer = referrer;
724 r.voiceInteractor = voiceInteractor;
725 r.activityInfo = info;
726 r.compatInfo = compatInfo;
728 r.persistentState = persistentState;
730 r.pendingResults = pendingResults;
731 r.pendingIntents = pendingNewIntents;
733 r.startsNotResumed = notResumed;
734 r.isForward = isForward;
736 r.profilerInfo = profilerInfo;
738 r.overrideConfig = overrideConfig;
739 updatePendingConfiguration(curConfig);
741 sendMessage(H.LAUNCH_ACTIVITY, r);
745 public final void scheduleRelaunchActivity(IBinder token,
746 List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents,
747 int configChanges, boolean notResumed, Configuration config,
748 Configuration overrideConfig, boolean preserveWindow) {
749 requestRelaunchActivity(token, pendingResults, pendingNewIntents,
750 configChanges, notResumed, config, overrideConfig, true, preserveWindow);
753 public final void scheduleNewIntent(List<ReferrerIntent> intents, IBinder token) {
754 NewIntentData data = new NewIntentData();
755 data.intents = intents;
758 sendMessage(H.NEW_INTENT, data);
761 public final void scheduleDestroyActivity(IBinder token, boolean finishing,
763 sendMessage(H.DESTROY_ACTIVITY, token, finishing ? 1 : 0,
767 public final void scheduleReceiver(Intent intent, ActivityInfo info,
768 CompatibilityInfo compatInfo, int resultCode, String data, Bundle extras,
769 boolean sync, int sendingUser, int processState) {
770 updateProcessState(processState, false);
771 ReceiverData r = new ReceiverData(intent, resultCode, data, extras,
772 sync, false, mAppThread.asBinder(), sendingUser);
774 r.compatInfo = compatInfo;
775 sendMessage(H.RECEIVER, r);
778 public final void scheduleCreateBackupAgent(ApplicationInfo app,
779 CompatibilityInfo compatInfo, int backupMode) {
780 CreateBackupAgentData d = new CreateBackupAgentData();
782 d.compatInfo = compatInfo;
783 d.backupMode = backupMode;
785 sendMessage(H.CREATE_BACKUP_AGENT, d);
788 public final void scheduleDestroyBackupAgent(ApplicationInfo app,
789 CompatibilityInfo compatInfo) {
790 CreateBackupAgentData d = new CreateBackupAgentData();
792 d.compatInfo = compatInfo;
794 sendMessage(H.DESTROY_BACKUP_AGENT, d);
797 public final void scheduleCreateService(IBinder token,
798 ServiceInfo info, CompatibilityInfo compatInfo, int processState) {
799 updateProcessState(processState, false);
800 CreateServiceData s = new CreateServiceData();
803 s.compatInfo = compatInfo;
805 sendMessage(H.CREATE_SERVICE, s);
808 public final void scheduleBindService(IBinder token, Intent intent,
809 boolean rebind, int processState) {
810 updateProcessState(processState, false);
811 BindServiceData s = new BindServiceData();
817 Slog.v(TAG, "scheduleBindService token=" + token + " intent=" + intent + " uid="
818 + Binder.getCallingUid() + " pid=" + Binder.getCallingPid());
819 sendMessage(H.BIND_SERVICE, s);
822 public final void scheduleUnbindService(IBinder token, Intent intent) {
823 BindServiceData s = new BindServiceData();
827 sendMessage(H.UNBIND_SERVICE, s);
830 public final void scheduleServiceArgs(IBinder token, boolean taskRemoved, int startId,
831 int flags ,Intent args) {
832 ServiceArgsData s = new ServiceArgsData();
834 s.taskRemoved = taskRemoved;
839 sendMessage(H.SERVICE_ARGS, s);
842 public final void scheduleStopService(IBinder token) {
843 sendMessage(H.STOP_SERVICE, token);
846 public final void bindApplication(String processName, ApplicationInfo appInfo,
847 List<ProviderInfo> providers, ComponentName instrumentationName,
848 ProfilerInfo profilerInfo, Bundle instrumentationArgs,
849 IInstrumentationWatcher instrumentationWatcher,
850 IUiAutomationConnection instrumentationUiConnection, int debugMode,
851 boolean enableBinderTracking, boolean trackAllocation,
852 boolean isRestrictedBackupMode, boolean persistent, Configuration config,
853 CompatibilityInfo compatInfo, Map<String, IBinder> services, Bundle coreSettings) {
855 if (services != null) {
856 // Setup the service cache in the ServiceManager
857 ServiceManager.initServiceCache(services);
860 setCoreSettings(coreSettings);
862 AppBindData data = new AppBindData();
863 data.processName = processName;
864 data.appInfo = appInfo;
865 data.providers = providers;
866 data.instrumentationName = instrumentationName;
867 data.instrumentationArgs = instrumentationArgs;
868 data.instrumentationWatcher = instrumentationWatcher;
869 data.instrumentationUiAutomationConnection = instrumentationUiConnection;
870 data.debugMode = debugMode;
871 data.enableBinderTracking = enableBinderTracking;
872 data.trackAllocation = trackAllocation;
873 data.restrictedBackupMode = isRestrictedBackupMode;
874 data.persistent = persistent;
875 data.config = config;
876 data.compatInfo = compatInfo;
877 data.initProfilerInfo = profilerInfo;
878 sendMessage(H.BIND_APPLICATION, data);
881 public final void scheduleExit() {
882 sendMessage(H.EXIT_APPLICATION, null);
885 public final void scheduleSuicide() {
886 sendMessage(H.SUICIDE, null);
889 public void scheduleConfigurationChanged(Configuration config) {
890 updatePendingConfiguration(config);
891 sendMessage(H.CONFIGURATION_CHANGED, config);
894 public void updateTimeZone() {
895 TimeZone.setDefault(null);
898 public void clearDnsCache() {
899 // a non-standard API to get this to libcore
900 InetAddress.clearDnsCache();
901 // Allow libcore to perform the necessary actions as it sees fit upon a network
902 // configuration change.
903 NetworkEventDispatcher.getInstance().onNetworkConfigurationChanged();
906 public void setHttpProxy(String host, String port, String exclList, Uri pacFileUrl) {
907 final ConnectivityManager cm = ConnectivityManager.from(getSystemContext());
908 final Network network = cm.getBoundNetworkForProcess();
909 if (network != null) {
910 Proxy.setHttpProxySystemProperty(cm.getDefaultProxy());
912 Proxy.setHttpProxySystemProperty(host, port, exclList, pacFileUrl);
916 public void processInBackground() {
917 mH.removeMessages(H.GC_WHEN_IDLE);
918 mH.sendMessage(mH.obtainMessage(H.GC_WHEN_IDLE));
921 public void dumpService(FileDescriptor fd, IBinder servicetoken, String[] args) {
922 DumpComponentInfo data = new DumpComponentInfo();
924 data.fd = ParcelFileDescriptor.dup(fd);
925 data.token = servicetoken;
927 sendMessage(H.DUMP_SERVICE, data, 0, 0, true /*async*/);
928 } catch (IOException e) {
929 Slog.w(TAG, "dumpService failed", e);
933 // This function exists to make sure all receiver dispatching is
934 // correctly ordered, since these are one-way calls and the binder driver
935 // applies transaction ordering per object for such calls.
936 public void scheduleRegisteredReceiver(IIntentReceiver receiver, Intent intent,
937 int resultCode, String dataStr, Bundle extras, boolean ordered,
938 boolean sticky, int sendingUser, int processState) throws RemoteException {
939 updateProcessState(processState, false);
940 receiver.performReceive(intent, resultCode, dataStr, extras, ordered,
941 sticky, sendingUser);
945 public void scheduleLowMemory() {
946 sendMessage(H.LOW_MEMORY, null);
950 public void scheduleActivityConfigurationChanged(
951 IBinder token, Configuration overrideConfig, boolean reportToActivity) {
952 sendMessage(H.ACTIVITY_CONFIGURATION_CHANGED,
953 new ActivityConfigChangeData(token, overrideConfig), reportToActivity ? 1 : 0);
957 public void profilerControl(boolean start, ProfilerInfo profilerInfo, int profileType) {
958 sendMessage(H.PROFILER_CONTROL, profilerInfo, start ? 1 : 0, profileType);
961 public void dumpHeap(boolean managed, String path, ParcelFileDescriptor fd) {
962 DumpHeapData dhd = new DumpHeapData();
965 sendMessage(H.DUMP_HEAP, dhd, managed ? 1 : 0, 0, true /*async*/);
968 public void setSchedulingGroup(int group) {
969 // Note: do this immediately, since going into the foreground
970 // should happen regardless of what pending work we have to do
971 // and the activity manager will wait for us to report back that
972 // we are done before sending us to the background.
974 Process.setProcessGroup(Process.myPid(), group);
975 } catch (Exception e) {
976 Slog.w(TAG, "Failed setting process group to " + group, e);
980 public void dispatchPackageBroadcast(int cmd, String[] packages) {
981 sendMessage(H.DISPATCH_PACKAGE_BROADCAST, packages, cmd);
984 public void scheduleCrash(String msg) {
985 sendMessage(H.SCHEDULE_CRASH, msg);
988 public void dumpActivity(FileDescriptor fd, IBinder activitytoken,
989 String prefix, String[] args) {
990 DumpComponentInfo data = new DumpComponentInfo();
992 data.fd = ParcelFileDescriptor.dup(fd);
993 data.token = activitytoken;
994 data.prefix = prefix;
996 sendMessage(H.DUMP_ACTIVITY, data, 0, 0, true /*async*/);
997 } catch (IOException e) {
998 Slog.w(TAG, "dumpActivity failed", e);
1002 public void dumpProvider(FileDescriptor fd, IBinder providertoken,
1004 DumpComponentInfo data = new DumpComponentInfo();
1006 data.fd = ParcelFileDescriptor.dup(fd);
1007 data.token = providertoken;
1009 sendMessage(H.DUMP_PROVIDER, data, 0, 0, true /*async*/);
1010 } catch (IOException e) {
1011 Slog.w(TAG, "dumpProvider failed", e);
1016 public void dumpMemInfo(FileDescriptor fd, Debug.MemoryInfo mem, boolean checkin,
1017 boolean dumpFullInfo, boolean dumpDalvik, boolean dumpSummaryOnly,
1018 boolean dumpUnreachable, String[] args) {
1019 FileOutputStream fout = new FileOutputStream(fd);
1020 PrintWriter pw = new FastPrintWriter(fout);
1022 dumpMemInfo(pw, mem, checkin, dumpFullInfo, dumpDalvik, dumpSummaryOnly, dumpUnreachable);
1028 private void dumpMemInfo(PrintWriter pw, Debug.MemoryInfo memInfo, boolean checkin,
1029 boolean dumpFullInfo, boolean dumpDalvik, boolean dumpSummaryOnly, boolean dumpUnreachable) {
1030 long nativeMax = Debug.getNativeHeapSize() / 1024;
1031 long nativeAllocated = Debug.getNativeHeapAllocatedSize() / 1024;
1032 long nativeFree = Debug.getNativeHeapFreeSize() / 1024;
1034 Runtime runtime = Runtime.getRuntime();
1035 runtime.gc(); // Do GC since countInstancesOfClass counts unreachable objects.
1036 long dalvikMax = runtime.totalMemory() / 1024;
1037 long dalvikFree = runtime.freeMemory() / 1024;
1038 long dalvikAllocated = dalvikMax - dalvikFree;
1039 long viewInstanceCount = ViewDebug.getViewInstanceCount();
1040 long viewRootInstanceCount = ViewDebug.getViewRootImplCount();
1041 long appContextInstanceCount = Debug.countInstancesOfClass(ContextImpl.class);
1042 long activityInstanceCount = Debug.countInstancesOfClass(Activity.class);
1043 int globalAssetCount = AssetManager.getGlobalAssetCount();
1044 int globalAssetManagerCount = AssetManager.getGlobalAssetManagerCount();
1045 int binderLocalObjectCount = Debug.getBinderLocalObjectCount();
1046 int binderProxyObjectCount = Debug.getBinderProxyObjectCount();
1047 int binderDeathObjectCount = Debug.getBinderDeathObjectCount();
1048 long parcelSize = Parcel.getGlobalAllocSize();
1049 long parcelCount = Parcel.getGlobalAllocCount();
1050 long openSslSocketCount = Debug.countInstancesOfClass(OpenSSLSocketImpl.class);
1051 SQLiteDebug.PagerStats stats = SQLiteDebug.getDatabaseInfo();
1053 dumpMemInfoTable(pw, memInfo, checkin, dumpFullInfo, dumpDalvik, dumpSummaryOnly,
1055 (mBoundApplication != null) ? mBoundApplication.processName : "unknown",
1056 nativeMax, nativeAllocated, nativeFree,
1057 dalvikMax, dalvikAllocated, dalvikFree);
1060 // NOTE: if you change anything significant below, also consider changing
1061 // ACTIVITY_THREAD_CHECKIN_VERSION.
1064 pw.print(viewInstanceCount); pw.print(',');
1065 pw.print(viewRootInstanceCount); pw.print(',');
1066 pw.print(appContextInstanceCount); pw.print(',');
1067 pw.print(activityInstanceCount); pw.print(',');
1069 pw.print(globalAssetCount); pw.print(',');
1070 pw.print(globalAssetManagerCount); pw.print(',');
1071 pw.print(binderLocalObjectCount); pw.print(',');
1072 pw.print(binderProxyObjectCount); pw.print(',');
1074 pw.print(binderDeathObjectCount); pw.print(',');
1075 pw.print(openSslSocketCount); pw.print(',');
1078 pw.print(stats.memoryUsed / 1024); pw.print(',');
1079 pw.print(stats.memoryUsed / 1024); pw.print(',');
1080 pw.print(stats.pageCacheOverflow / 1024); pw.print(',');
1081 pw.print(stats.largestMemAlloc / 1024);
1082 for (int i = 0; i < stats.dbStats.size(); i++) {
1083 DbStats dbStats = stats.dbStats.get(i);
1084 pw.print(','); pw.print(dbStats.dbName);
1085 pw.print(','); pw.print(dbStats.pageSize);
1086 pw.print(','); pw.print(dbStats.dbSize);
1087 pw.print(','); pw.print(dbStats.lookaside);
1088 pw.print(','); pw.print(dbStats.cache);
1089 pw.print(','); pw.print(dbStats.cache);
1097 pw.println(" Objects");
1098 printRow(pw, TWO_COUNT_COLUMNS, "Views:", viewInstanceCount, "ViewRootImpl:",
1099 viewRootInstanceCount);
1101 printRow(pw, TWO_COUNT_COLUMNS, "AppContexts:", appContextInstanceCount,
1102 "Activities:", activityInstanceCount);
1104 printRow(pw, TWO_COUNT_COLUMNS, "Assets:", globalAssetCount,
1105 "AssetManagers:", globalAssetManagerCount);
1107 printRow(pw, TWO_COUNT_COLUMNS, "Local Binders:", binderLocalObjectCount,
1108 "Proxy Binders:", binderProxyObjectCount);
1109 printRow(pw, TWO_COUNT_COLUMNS, "Parcel memory:", parcelSize/1024,
1110 "Parcel count:", parcelCount);
1111 printRow(pw, TWO_COUNT_COLUMNS, "Death Recipients:", binderDeathObjectCount,
1112 "OpenSSL Sockets:", openSslSocketCount);
1117 printRow(pw, ONE_COUNT_COLUMN, "MEMORY_USED:", stats.memoryUsed / 1024);
1118 printRow(pw, TWO_COUNT_COLUMNS, "PAGECACHE_OVERFLOW:",
1119 stats.pageCacheOverflow / 1024, "MALLOC_SIZE:", stats.largestMemAlloc / 1024);
1121 int N = stats.dbStats.size();
1123 pw.println(" DATABASES");
1124 printRow(pw, " %8s %8s %14s %14s %s", "pgsz", "dbsz", "Lookaside(b)", "cache",
1126 for (int i = 0; i < N; i++) {
1127 DbStats dbStats = stats.dbStats.get(i);
1128 printRow(pw, DB_INFO_FORMAT,
1129 (dbStats.pageSize > 0) ? String.valueOf(dbStats.pageSize) : " ",
1130 (dbStats.dbSize > 0) ? String.valueOf(dbStats.dbSize) : " ",
1131 (dbStats.lookaside > 0) ? String.valueOf(dbStats.lookaside) : " ",
1132 dbStats.cache, dbStats.dbName);
1137 String assetAlloc = AssetManager.getAssetAllocations();
1138 if (assetAlloc != null) {
1140 pw.println(" Asset Allocations");
1141 pw.print(assetAlloc);
1144 // Unreachable native memory
1145 if (dumpUnreachable) {
1146 boolean showContents = ((mBoundApplication != null)
1147 && ((mBoundApplication.appInfo.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0))
1148 || android.os.Build.IS_DEBUGGABLE;
1150 pw.println(" Unreachable memory");
1151 pw.print(Debug.getUnreachableMemory(100, showContents));
1156 public void dumpGfxInfo(FileDescriptor fd, String[] args) {
1157 dumpGraphicsInfo(fd);
1158 WindowManagerGlobal.getInstance().dumpGfxInfo(fd, args);
1161 private void dumpDatabaseInfo(FileDescriptor fd, String[] args) {
1162 PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd));
1163 PrintWriterPrinter printer = new PrintWriterPrinter(pw);
1164 SQLiteDebug.dump(printer, args);
1169 public void dumpDbInfo(final FileDescriptor fd, final String[] args) {
1170 if (mSystemThread) {
1171 // Ensure this invocation is asynchronous to prevent writer waiting if buffer cannot
1172 // be consumed. But it must duplicate the file descriptor first, since caller might
1174 final ParcelFileDescriptor dup;
1176 dup = ParcelFileDescriptor.dup(fd);
1177 } catch (IOException e) {
1178 Log.w(TAG, "Could not dup FD " + fd.getInt$());
1182 AsyncTask.THREAD_POOL_EXECUTOR.execute(new Runnable() {
1186 dumpDatabaseInfo(dup.getFileDescriptor(), args);
1188 IoUtils.closeQuietly(dup);
1193 dumpDatabaseInfo(fd, args);
1198 public void unstableProviderDied(IBinder provider) {
1199 sendMessage(H.UNSTABLE_PROVIDER_DIED, provider);
1203 public void requestAssistContextExtras(IBinder activityToken, IBinder requestToken,
1204 int requestType, int sessionId) {
1205 RequestAssistContextExtras cmd = new RequestAssistContextExtras();
1206 cmd.activityToken = activityToken;
1207 cmd.requestToken = requestToken;
1208 cmd.requestType = requestType;
1209 cmd.sessionId = sessionId;
1210 sendMessage(H.REQUEST_ASSIST_CONTEXT_EXTRAS, cmd);
1213 public void setCoreSettings(Bundle coreSettings) {
1214 sendMessage(H.SET_CORE_SETTINGS, coreSettings);
1217 public void updatePackageCompatibilityInfo(String pkg, CompatibilityInfo info) {
1218 UpdateCompatibilityData ucd = new UpdateCompatibilityData();
1221 sendMessage(H.UPDATE_PACKAGE_COMPATIBILITY_INFO, ucd);
1224 public void scheduleTrimMemory(int level) {
1225 sendMessage(H.TRIM_MEMORY, null, level);
1228 public void scheduleTranslucentConversionComplete(IBinder token, boolean drawComplete) {
1229 sendMessage(H.TRANSLUCENT_CONVERSION_COMPLETE, token, drawComplete ? 1 : 0);
1232 public void scheduleOnNewActivityOptions(IBinder token, ActivityOptions options) {
1233 sendMessage(H.ON_NEW_ACTIVITY_OPTIONS,
1234 new Pair<IBinder, ActivityOptions>(token, options));
1237 public void setProcessState(int state) {
1238 updateProcessState(state, true);
1241 public void updateProcessState(int processState, boolean fromIpc) {
1242 synchronized (this) {
1243 if (mLastProcessState != processState) {
1244 mLastProcessState = processState;
1245 // Update Dalvik state based on ActivityManager.PROCESS_STATE_* constants.
1246 final int DALVIK_PROCESS_STATE_JANK_PERCEPTIBLE = 0;
1247 final int DALVIK_PROCESS_STATE_JANK_IMPERCEPTIBLE = 1;
1248 int dalvikProcessState = DALVIK_PROCESS_STATE_JANK_IMPERCEPTIBLE;
1249 // TODO: Tune this since things like gmail sync are important background but not jank perceptible.
1250 if (processState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
1251 dalvikProcessState = DALVIK_PROCESS_STATE_JANK_PERCEPTIBLE;
1253 VMRuntime.getRuntime().updateProcessState(dalvikProcessState);
1255 Slog.i(TAG, "******************* PROCESS STATE CHANGED TO: " + processState
1256 + (fromIpc ? " (from ipc": ""));
1263 public void scheduleInstallProvider(ProviderInfo provider) {
1264 sendMessage(H.INSTALL_PROVIDER, provider);
1268 public final void updateTimePrefs(boolean is24Hour) {
1269 DateFormat.set24HourTimePref(is24Hour);
1273 public void scheduleCancelVisibleBehind(IBinder token) {
1274 sendMessage(H.CANCEL_VISIBLE_BEHIND, token);
1278 public void scheduleBackgroundVisibleBehindChanged(IBinder token, boolean visible) {
1279 sendMessage(H.BACKGROUND_VISIBLE_BEHIND_CHANGED, token, visible ? 1 : 0);
1283 public void scheduleEnterAnimationComplete(IBinder token) {
1284 sendMessage(H.ENTER_ANIMATION_COMPLETE, token);
1288 public void notifyCleartextNetwork(byte[] firstPacket) {
1289 if (StrictMode.vmCleartextNetworkEnabled()) {
1290 StrictMode.onCleartextNetworkDetected(firstPacket);
1295 public void startBinderTracking() {
1296 sendMessage(H.START_BINDER_TRACKING, null);
1300 public void stopBinderTrackingAndDump(FileDescriptor fd) {
1302 sendMessage(H.STOP_BINDER_TRACKING_AND_DUMP, ParcelFileDescriptor.dup(fd));
1303 } catch (IOException e) {
1308 public void scheduleMultiWindowModeChanged(IBinder token, boolean isInMultiWindowMode)
1309 throws RemoteException {
1310 sendMessage(H.MULTI_WINDOW_MODE_CHANGED, token, isInMultiWindowMode ? 1 : 0);
1314 public void schedulePictureInPictureModeChanged(IBinder token, boolean isInPipMode)
1315 throws RemoteException {
1316 sendMessage(H.PICTURE_IN_PICTURE_MODE_CHANGED, token, isInPipMode ? 1 : 0);
1320 public void scheduleLocalVoiceInteractionStarted(IBinder token,
1321 IVoiceInteractor voiceInteractor) throws RemoteException {
1322 SomeArgs args = SomeArgs.obtain();
1324 args.arg2 = voiceInteractor;
1325 sendMessage(H.LOCAL_VOICE_INTERACTION_STARTED, args);
1329 private int getLifecycleSeq() {
1330 synchronized (mResourcesManager) {
1331 return mLifecycleSeq++;
1335 private class H extends Handler {
1336 public static final int LAUNCH_ACTIVITY = 100;
1337 public static final int PAUSE_ACTIVITY = 101;
1338 public static final int PAUSE_ACTIVITY_FINISHING= 102;
1339 public static final int STOP_ACTIVITY_SHOW = 103;
1340 public static final int STOP_ACTIVITY_HIDE = 104;
1341 public static final int SHOW_WINDOW = 105;
1342 public static final int HIDE_WINDOW = 106;
1343 public static final int RESUME_ACTIVITY = 107;
1344 public static final int SEND_RESULT = 108;
1345 public static final int DESTROY_ACTIVITY = 109;
1346 public static final int BIND_APPLICATION = 110;
1347 public static final int EXIT_APPLICATION = 111;
1348 public static final int NEW_INTENT = 112;
1349 public static final int RECEIVER = 113;
1350 public static final int CREATE_SERVICE = 114;
1351 public static final int SERVICE_ARGS = 115;
1352 public static final int STOP_SERVICE = 116;
1354 public static final int CONFIGURATION_CHANGED = 118;
1355 public static final int CLEAN_UP_CONTEXT = 119;
1356 public static final int GC_WHEN_IDLE = 120;
1357 public static final int BIND_SERVICE = 121;
1358 public static final int UNBIND_SERVICE = 122;
1359 public static final int DUMP_SERVICE = 123;
1360 public static final int LOW_MEMORY = 124;
1361 public static final int ACTIVITY_CONFIGURATION_CHANGED = 125;
1362 public static final int RELAUNCH_ACTIVITY = 126;
1363 public static final int PROFILER_CONTROL = 127;
1364 public static final int CREATE_BACKUP_AGENT = 128;
1365 public static final int DESTROY_BACKUP_AGENT = 129;
1366 public static final int SUICIDE = 130;
1367 public static final int REMOVE_PROVIDER = 131;
1368 public static final int ENABLE_JIT = 132;
1369 public static final int DISPATCH_PACKAGE_BROADCAST = 133;
1370 public static final int SCHEDULE_CRASH = 134;
1371 public static final int DUMP_HEAP = 135;
1372 public static final int DUMP_ACTIVITY = 136;
1373 public static final int SLEEPING = 137;
1374 public static final int SET_CORE_SETTINGS = 138;
1375 public static final int UPDATE_PACKAGE_COMPATIBILITY_INFO = 139;
1376 public static final int TRIM_MEMORY = 140;
1377 public static final int DUMP_PROVIDER = 141;
1378 public static final int UNSTABLE_PROVIDER_DIED = 142;
1379 public static final int REQUEST_ASSIST_CONTEXT_EXTRAS = 143;
1380 public static final int TRANSLUCENT_CONVERSION_COMPLETE = 144;
1381 public static final int INSTALL_PROVIDER = 145;
1382 public static final int ON_NEW_ACTIVITY_OPTIONS = 146;
1383 public static final int CANCEL_VISIBLE_BEHIND = 147;
1384 public static final int BACKGROUND_VISIBLE_BEHIND_CHANGED = 148;
1385 public static final int ENTER_ANIMATION_COMPLETE = 149;
1386 public static final int START_BINDER_TRACKING = 150;
1387 public static final int STOP_BINDER_TRACKING_AND_DUMP = 151;
1388 public static final int MULTI_WINDOW_MODE_CHANGED = 152;
1389 public static final int PICTURE_IN_PICTURE_MODE_CHANGED = 153;
1390 public static final int LOCAL_VOICE_INTERACTION_STARTED = 154;
1392 String codeToString(int code) {
1393 if (DEBUG_MESSAGES) {
1395 case LAUNCH_ACTIVITY: return "LAUNCH_ACTIVITY";
1396 case PAUSE_ACTIVITY: return "PAUSE_ACTIVITY";
1397 case PAUSE_ACTIVITY_FINISHING: return "PAUSE_ACTIVITY_FINISHING";
1398 case STOP_ACTIVITY_SHOW: return "STOP_ACTIVITY_SHOW";
1399 case STOP_ACTIVITY_HIDE: return "STOP_ACTIVITY_HIDE";
1400 case SHOW_WINDOW: return "SHOW_WINDOW";
1401 case HIDE_WINDOW: return "HIDE_WINDOW";
1402 case RESUME_ACTIVITY: return "RESUME_ACTIVITY";
1403 case SEND_RESULT: return "SEND_RESULT";
1404 case DESTROY_ACTIVITY: return "DESTROY_ACTIVITY";
1405 case BIND_APPLICATION: return "BIND_APPLICATION";
1406 case EXIT_APPLICATION: return "EXIT_APPLICATION";
1407 case NEW_INTENT: return "NEW_INTENT";
1408 case RECEIVER: return "RECEIVER";
1409 case CREATE_SERVICE: return "CREATE_SERVICE";
1410 case SERVICE_ARGS: return "SERVICE_ARGS";
1411 case STOP_SERVICE: return "STOP_SERVICE";
1412 case CONFIGURATION_CHANGED: return "CONFIGURATION_CHANGED";
1413 case CLEAN_UP_CONTEXT: return "CLEAN_UP_CONTEXT";
1414 case GC_WHEN_IDLE: return "GC_WHEN_IDLE";
1415 case BIND_SERVICE: return "BIND_SERVICE";
1416 case UNBIND_SERVICE: return "UNBIND_SERVICE";
1417 case DUMP_SERVICE: return "DUMP_SERVICE";
1418 case LOW_MEMORY: return "LOW_MEMORY";
1419 case ACTIVITY_CONFIGURATION_CHANGED: return "ACTIVITY_CONFIGURATION_CHANGED";
1420 case RELAUNCH_ACTIVITY: return "RELAUNCH_ACTIVITY";
1421 case PROFILER_CONTROL: return "PROFILER_CONTROL";
1422 case CREATE_BACKUP_AGENT: return "CREATE_BACKUP_AGENT";
1423 case DESTROY_BACKUP_AGENT: return "DESTROY_BACKUP_AGENT";
1424 case SUICIDE: return "SUICIDE";
1425 case REMOVE_PROVIDER: return "REMOVE_PROVIDER";
1426 case ENABLE_JIT: return "ENABLE_JIT";
1427 case DISPATCH_PACKAGE_BROADCAST: return "DISPATCH_PACKAGE_BROADCAST";
1428 case SCHEDULE_CRASH: return "SCHEDULE_CRASH";
1429 case DUMP_HEAP: return "DUMP_HEAP";
1430 case DUMP_ACTIVITY: return "DUMP_ACTIVITY";
1431 case SLEEPING: return "SLEEPING";
1432 case SET_CORE_SETTINGS: return "SET_CORE_SETTINGS";
1433 case UPDATE_PACKAGE_COMPATIBILITY_INFO: return "UPDATE_PACKAGE_COMPATIBILITY_INFO";
1434 case TRIM_MEMORY: return "TRIM_MEMORY";
1435 case DUMP_PROVIDER: return "DUMP_PROVIDER";
1436 case UNSTABLE_PROVIDER_DIED: return "UNSTABLE_PROVIDER_DIED";
1437 case REQUEST_ASSIST_CONTEXT_EXTRAS: return "REQUEST_ASSIST_CONTEXT_EXTRAS";
1438 case TRANSLUCENT_CONVERSION_COMPLETE: return "TRANSLUCENT_CONVERSION_COMPLETE";
1439 case INSTALL_PROVIDER: return "INSTALL_PROVIDER";
1440 case ON_NEW_ACTIVITY_OPTIONS: return "ON_NEW_ACTIVITY_OPTIONS";
1441 case CANCEL_VISIBLE_BEHIND: return "CANCEL_VISIBLE_BEHIND";
1442 case BACKGROUND_VISIBLE_BEHIND_CHANGED: return "BACKGROUND_VISIBLE_BEHIND_CHANGED";
1443 case ENTER_ANIMATION_COMPLETE: return "ENTER_ANIMATION_COMPLETE";
1444 case MULTI_WINDOW_MODE_CHANGED: return "MULTI_WINDOW_MODE_CHANGED";
1445 case PICTURE_IN_PICTURE_MODE_CHANGED: return "PICTURE_IN_PICTURE_MODE_CHANGED";
1446 case LOCAL_VOICE_INTERACTION_STARTED: return "LOCAL_VOICE_INTERACTION_STARTED";
1449 return Integer.toString(code);
1451 public void handleMessage(Message msg) {
1452 if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
1454 case LAUNCH_ACTIVITY: {
1455 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
1456 final ActivityClientRecord r = (ActivityClientRecord) msg.obj;
1458 r.packageInfo = getPackageInfoNoCheck(
1459 r.activityInfo.applicationInfo, r.compatInfo);
1460 handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");
1461 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1463 case RELAUNCH_ACTIVITY: {
1464 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityRestart");
1465 ActivityClientRecord r = (ActivityClientRecord)msg.obj;
1466 handleRelaunchActivity(r);
1467 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1469 case PAUSE_ACTIVITY: {
1470 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
1471 SomeArgs args = (SomeArgs) msg.obj;
1472 handlePauseActivity((IBinder) args.arg1, false,
1473 (args.argi1 & USER_LEAVING) != 0, args.argi2,
1474 (args.argi1 & DONT_REPORT) != 0, args.argi3);
1476 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1478 case PAUSE_ACTIVITY_FINISHING: {
1479 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
1480 SomeArgs args = (SomeArgs) msg.obj;
1481 handlePauseActivity((IBinder) args.arg1, true, (args.argi1 & USER_LEAVING) != 0,
1482 args.argi2, (args.argi1 & DONT_REPORT) != 0, args.argi3);
1483 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1485 case STOP_ACTIVITY_SHOW: {
1486 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStop");
1487 SomeArgs args = (SomeArgs) msg.obj;
1488 handleStopActivity((IBinder) args.arg1, true, args.argi2, args.argi3);
1489 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1491 case STOP_ACTIVITY_HIDE: {
1492 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStop");
1493 SomeArgs args = (SomeArgs) msg.obj;
1494 handleStopActivity((IBinder) args.arg1, false, args.argi2, args.argi3);
1495 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1498 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityShowWindow");
1499 handleWindowVisibility((IBinder)msg.obj, true);
1500 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1503 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityHideWindow");
1504 handleWindowVisibility((IBinder)msg.obj, false);
1505 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1507 case RESUME_ACTIVITY:
1508 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityResume");
1509 SomeArgs args = (SomeArgs) msg.obj;
1510 handleResumeActivity((IBinder) args.arg1, true, args.argi1 != 0, true,
1511 args.argi3, "RESUME_ACTIVITY");
1512 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1515 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityDeliverResult");
1516 handleSendResult((ResultData)msg.obj);
1517 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1519 case DESTROY_ACTIVITY:
1520 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityDestroy");
1521 handleDestroyActivity((IBinder)msg.obj, msg.arg1 != 0,
1523 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1525 case BIND_APPLICATION:
1526 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
1527 AppBindData data = (AppBindData)msg.obj;
1528 handleBindApplication(data);
1529 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1531 case EXIT_APPLICATION:
1532 if (mInitialApplication != null) {
1533 mInitialApplication.onTerminate();
1535 Looper.myLooper().quit();
1538 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityNewIntent");
1539 handleNewIntent((NewIntentData)msg.obj);
1540 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1543 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "broadcastReceiveComp");
1544 handleReceiver((ReceiverData)msg.obj);
1546 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1548 case CREATE_SERVICE:
1549 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, ("serviceCreate: " + String.valueOf(msg.obj)));
1550 handleCreateService((CreateServiceData)msg.obj);
1551 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1554 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceBind");
1555 handleBindService((BindServiceData)msg.obj);
1556 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1558 case UNBIND_SERVICE:
1559 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceUnbind");
1560 handleUnbindService((BindServiceData)msg.obj);
1561 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1564 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, ("serviceStart: " + String.valueOf(msg.obj)));
1565 handleServiceArgs((ServiceArgsData)msg.obj);
1566 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1569 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceStop");
1570 handleStopService((IBinder)msg.obj);
1572 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1574 case CONFIGURATION_CHANGED:
1575 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "configChanged");
1576 mCurDefaultDisplayDpi = ((Configuration)msg.obj).densityDpi;
1577 handleConfigurationChanged((Configuration)msg.obj, null);
1578 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1580 case CLEAN_UP_CONTEXT:
1581 ContextCleanupInfo cci = (ContextCleanupInfo)msg.obj;
1582 cci.context.performFinalCleanup(cci.who, cci.what);
1588 handleDumpService((DumpComponentInfo)msg.obj);
1591 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "lowMemory");
1593 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1595 case ACTIVITY_CONFIGURATION_CHANGED:
1596 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityConfigChanged");
1597 handleActivityConfigurationChanged((ActivityConfigChangeData) msg.obj,
1598 msg.arg1 == 1 ? REPORT_TO_ACTIVITY : !REPORT_TO_ACTIVITY);
1599 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1601 case PROFILER_CONTROL:
1602 handleProfilerControl(msg.arg1 != 0, (ProfilerInfo)msg.obj, msg.arg2);
1604 case CREATE_BACKUP_AGENT:
1605 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "backupCreateAgent");
1606 handleCreateBackupAgent((CreateBackupAgentData)msg.obj);
1607 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1609 case DESTROY_BACKUP_AGENT:
1610 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "backupDestroyAgent");
1611 handleDestroyBackupAgent((CreateBackupAgentData)msg.obj);
1612 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1615 Process.killProcess(Process.myPid());
1617 case REMOVE_PROVIDER:
1618 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "providerRemove");
1619 completeRemoveProvider((ProviderRefCount)msg.obj);
1620 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1625 case DISPATCH_PACKAGE_BROADCAST:
1626 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "broadcastPackage");
1627 handleDispatchPackageBroadcast(msg.arg1, (String[])msg.obj);
1628 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1630 case SCHEDULE_CRASH:
1631 throw new RemoteServiceException((String)msg.obj);
1633 handleDumpHeap(msg.arg1 != 0, (DumpHeapData)msg.obj);
1636 handleDumpActivity((DumpComponentInfo)msg.obj);
1639 handleDumpProvider((DumpComponentInfo)msg.obj);
1642 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "sleeping");
1643 handleSleeping((IBinder)msg.obj, msg.arg1 != 0);
1644 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1646 case SET_CORE_SETTINGS:
1647 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "setCoreSettings");
1648 handleSetCoreSettings((Bundle) msg.obj);
1649 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1651 case UPDATE_PACKAGE_COMPATIBILITY_INFO:
1652 handleUpdatePackageCompatibilityInfo((UpdateCompatibilityData)msg.obj);
1655 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "trimMemory");
1656 handleTrimMemory(msg.arg1);
1657 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1659 case UNSTABLE_PROVIDER_DIED:
1660 handleUnstableProviderDied((IBinder)msg.obj, false);
1662 case REQUEST_ASSIST_CONTEXT_EXTRAS:
1663 handleRequestAssistContextExtras((RequestAssistContextExtras)msg.obj);
1665 case TRANSLUCENT_CONVERSION_COMPLETE:
1666 handleTranslucentConversionComplete((IBinder)msg.obj, msg.arg1 == 1);
1668 case INSTALL_PROVIDER:
1669 handleInstallProvider((ProviderInfo) msg.obj);
1671 case ON_NEW_ACTIVITY_OPTIONS:
1672 Pair<IBinder, ActivityOptions> pair = (Pair<IBinder, ActivityOptions>) msg.obj;
1673 onNewActivityOptions(pair.first, pair.second);
1675 case CANCEL_VISIBLE_BEHIND:
1676 handleCancelVisibleBehind((IBinder) msg.obj);
1678 case BACKGROUND_VISIBLE_BEHIND_CHANGED:
1679 handleOnBackgroundVisibleBehindChanged((IBinder) msg.obj, msg.arg1 > 0);
1681 case ENTER_ANIMATION_COMPLETE:
1682 handleEnterAnimationComplete((IBinder) msg.obj);
1684 case START_BINDER_TRACKING:
1685 handleStartBinderTracking();
1687 case STOP_BINDER_TRACKING_AND_DUMP:
1688 handleStopBinderTrackingAndDump((ParcelFileDescriptor) msg.obj);
1690 case MULTI_WINDOW_MODE_CHANGED:
1691 handleMultiWindowModeChanged((IBinder) msg.obj, msg.arg1 == 1);
1693 case PICTURE_IN_PICTURE_MODE_CHANGED:
1694 handlePictureInPictureModeChanged((IBinder) msg.obj, msg.arg1 == 1);
1696 case LOCAL_VOICE_INTERACTION_STARTED:
1697 handleLocalVoiceInteractionStarted((IBinder) ((SomeArgs) msg.obj).arg1,
1698 (IVoiceInteractor) ((SomeArgs) msg.obj).arg2);
1701 Object obj = msg.obj;
1702 if (obj instanceof SomeArgs) {
1703 ((SomeArgs) obj).recycle();
1705 if (DEBUG_MESSAGES) Slog.v(TAG, "<<< done: " + codeToString(msg.what));
1708 private void maybeSnapshot() {
1709 if (mBoundApplication != null && SamplingProfilerIntegration.isEnabled()) {
1710 // convert the *private* ActivityThread.PackageInfo to *public* known
1711 // android.content.pm.PackageInfo
1712 String packageName = mBoundApplication.info.mPackageName;
1713 android.content.pm.PackageInfo packageInfo = null;
1715 Context context = getSystemContext();
1716 if(context == null) {
1717 Log.e(TAG, "cannot get a valid context");
1720 PackageManager pm = context.getPackageManager();
1722 Log.e(TAG, "cannot get a valid PackageManager");
1725 packageInfo = pm.getPackageInfo(
1726 packageName, PackageManager.GET_ACTIVITIES);
1727 } catch (NameNotFoundException e) {
1728 Log.e(TAG, "cannot get package info for " + packageName, e);
1730 SamplingProfilerIntegration.writeSnapshot(mBoundApplication.processName, packageInfo);
1735 private class Idler implements MessageQueue.IdleHandler {
1737 public final boolean queueIdle() {
1738 ActivityClientRecord a = mNewActivities;
1739 boolean stopProfiling = false;
1740 if (mBoundApplication != null && mProfiler.profileFd != null
1741 && mProfiler.autoStopProfiler) {
1742 stopProfiling = true;
1745 mNewActivities = null;
1746 IActivityManager am = ActivityManagerNative.getDefault();
1747 ActivityClientRecord prev;
1749 if (localLOGV) Slog.v(
1750 TAG, "Reporting idle of " + a +
1752 (a.activity != null && a.activity.mFinished));
1753 if (a.activity != null && !a.activity.mFinished) {
1755 am.activityIdle(a.token, a.createdConfig, stopProfiling);
1756 a.createdConfig = null;
1757 } catch (RemoteException ex) {
1758 throw ex.rethrowFromSystemServer();
1763 prev.nextIdle = null;
1764 } while (a != null);
1766 if (stopProfiling) {
1767 mProfiler.stopProfiling();
1774 final class GcIdler implements MessageQueue.IdleHandler {
1776 public final boolean queueIdle() {
1782 public static ActivityThread currentActivityThread() {
1783 return sCurrentActivityThread;
1786 public static boolean isSystem() {
1787 return (sCurrentActivityThread != null) ? sCurrentActivityThread.mSystemThread : false;
1790 public static String currentOpPackageName() {
1791 ActivityThread am = currentActivityThread();
1792 return (am != null && am.getApplication() != null)
1793 ? am.getApplication().getOpPackageName() : null;
1796 public static String currentPackageName() {
1797 ActivityThread am = currentActivityThread();
1798 return (am != null && am.mBoundApplication != null)
1799 ? am.mBoundApplication.appInfo.packageName : null;
1802 public static String currentProcessName() {
1803 ActivityThread am = currentActivityThread();
1804 return (am != null && am.mBoundApplication != null)
1805 ? am.mBoundApplication.processName : null;
1808 public static Application currentApplication() {
1809 ActivityThread am = currentActivityThread();
1810 return am != null ? am.mInitialApplication : null;
1813 public static IPackageManager getPackageManager() {
1814 if (sPackageManager != null) {
1815 //Slog.v("PackageManager", "returning cur default = " + sPackageManager);
1816 return sPackageManager;
1818 IBinder b = ServiceManager.getService("package");
1819 //Slog.v("PackageManager", "default service binder = " + b);
1820 sPackageManager = IPackageManager.Stub.asInterface(b);
1821 //Slog.v("PackageManager", "default service = " + sPackageManager);
1822 return sPackageManager;
1825 private Configuration mMainThreadConfig = new Configuration();
1827 Configuration applyConfigCompatMainThread(int displayDensity, Configuration config,
1828 CompatibilityInfo compat) {
1829 if (config == null) {
1832 if (!compat.supportsScreen()) {
1833 mMainThreadConfig.setTo(config);
1834 config = mMainThreadConfig;
1835 compat.applyToConfiguration(displayDensity, config);
1841 * Creates the top level resources for the given package. Will return an existing
1842 * Resources if one has already been created.
1844 Resources getTopLevelResources(String resDir, String[] splitResDirs, String[] overlayDirs,
1845 String[] libDirs, int displayId, LoadedApk pkgInfo) {
1846 return mResourcesManager.getResources(null, resDir, splitResDirs, overlayDirs, libDirs,
1847 displayId, null, pkgInfo.getCompatibilityInfo(), pkgInfo.getClassLoader());
1850 final Handler getHandler() {
1854 public final LoadedApk getPackageInfo(String packageName, CompatibilityInfo compatInfo,
1856 return getPackageInfo(packageName, compatInfo, flags, UserHandle.myUserId());
1859 public final LoadedApk getPackageInfo(String packageName, CompatibilityInfo compatInfo,
1860 int flags, int userId) {
1861 final boolean differentUser = (UserHandle.myUserId() != userId);
1862 synchronized (mResourcesManager) {
1863 WeakReference<LoadedApk> ref;
1864 if (differentUser) {
1865 // Caching not supported across users
1867 } else if ((flags & Context.CONTEXT_INCLUDE_CODE) != 0) {
1868 ref = mPackages.get(packageName);
1870 ref = mResourcePackages.get(packageName);
1873 LoadedApk packageInfo = ref != null ? ref.get() : null;
1874 //Slog.i(TAG, "getPackageInfo " + packageName + ": " + packageInfo);
1875 //if (packageInfo != null) Slog.i(TAG, "isUptoDate " + packageInfo.mResDir
1876 // + ": " + packageInfo.mResources.getAssets().isUpToDate());
1877 if (packageInfo != null && (packageInfo.mResources == null
1878 || packageInfo.mResources.getAssets().isUpToDate())) {
1879 if (packageInfo.isSecurityViolation()
1880 && (flags&Context.CONTEXT_IGNORE_SECURITY) == 0) {
1881 throw new SecurityException(
1882 "Requesting code from " + packageName
1883 + " to be run in process "
1884 + mBoundApplication.processName
1885 + "/" + mBoundApplication.appInfo.uid);
1891 ApplicationInfo ai = null;
1893 ai = getPackageManager().getApplicationInfo(packageName,
1894 PackageManager.GET_SHARED_LIBRARY_FILES
1895 | PackageManager.MATCH_DEBUG_TRIAGED_MISSING,
1897 } catch (RemoteException e) {
1898 throw e.rethrowFromSystemServer();
1902 return getPackageInfo(ai, compatInfo, flags);
1908 public final LoadedApk getPackageInfo(ApplicationInfo ai, CompatibilityInfo compatInfo,
1910 boolean includeCode = (flags&Context.CONTEXT_INCLUDE_CODE) != 0;
1911 boolean securityViolation = includeCode && ai.uid != 0
1912 && ai.uid != Process.SYSTEM_UID && (mBoundApplication != null
1913 ? !UserHandle.isSameApp(ai.uid, mBoundApplication.appInfo.uid)
1915 boolean registerPackage = includeCode && (flags&Context.CONTEXT_REGISTER_PACKAGE) != 0;
1916 if ((flags&(Context.CONTEXT_INCLUDE_CODE
1917 |Context.CONTEXT_IGNORE_SECURITY))
1918 == Context.CONTEXT_INCLUDE_CODE) {
1919 if (securityViolation) {
1920 String msg = "Requesting code from " + ai.packageName
1921 + " (with uid " + ai.uid + ")";
1922 if (mBoundApplication != null) {
1923 msg = msg + " to be run in process "
1924 + mBoundApplication.processName + " (with uid "
1925 + mBoundApplication.appInfo.uid + ")";
1927 throw new SecurityException(msg);
1930 return getPackageInfo(ai, compatInfo, null, securityViolation, includeCode,
1934 public final LoadedApk getPackageInfoNoCheck(ApplicationInfo ai,
1935 CompatibilityInfo compatInfo) {
1936 return getPackageInfo(ai, compatInfo, null, false, true, false);
1939 public final LoadedApk peekPackageInfo(String packageName, boolean includeCode) {
1940 synchronized (mResourcesManager) {
1941 WeakReference<LoadedApk> ref;
1943 ref = mPackages.get(packageName);
1945 ref = mResourcePackages.get(packageName);
1947 return ref != null ? ref.get() : null;
1951 private LoadedApk getPackageInfo(ApplicationInfo aInfo, CompatibilityInfo compatInfo,
1952 ClassLoader baseLoader, boolean securityViolation, boolean includeCode,
1953 boolean registerPackage) {
1954 final boolean differentUser = (UserHandle.myUserId() != UserHandle.getUserId(aInfo.uid));
1955 synchronized (mResourcesManager) {
1956 WeakReference<LoadedApk> ref;
1957 if (differentUser) {
1958 // Caching not supported across users
1960 } else if (includeCode) {
1961 ref = mPackages.get(aInfo.packageName);
1963 ref = mResourcePackages.get(aInfo.packageName);
1966 LoadedApk packageInfo = ref != null ? ref.get() : null;
1967 if (packageInfo == null || (packageInfo.mResources != null
1968 && !packageInfo.mResources.getAssets().isUpToDate())) {
1969 if (localLOGV) Slog.v(TAG, (includeCode ? "Loading code package "
1970 : "Loading resource-only package ") + aInfo.packageName
1971 + " (in " + (mBoundApplication != null
1972 ? mBoundApplication.processName : null)
1975 new LoadedApk(this, aInfo, compatInfo, baseLoader,
1976 securityViolation, includeCode &&
1977 (aInfo.flags&ApplicationInfo.FLAG_HAS_CODE) != 0, registerPackage);
1979 if (mSystemThread && "android".equals(aInfo.packageName)) {
1980 packageInfo.installSystemApplicationInfo(aInfo,
1981 getSystemContext().mPackageInfo.getClassLoader());
1984 if (differentUser) {
1985 // Caching not supported across users
1986 } else if (includeCode) {
1987 mPackages.put(aInfo.packageName,
1988 new WeakReference<LoadedApk>(packageInfo));
1990 mResourcePackages.put(aInfo.packageName,
1991 new WeakReference<LoadedApk>(packageInfo));
1999 mResourcesManager = ResourcesManager.getInstance();
2002 public ApplicationThread getApplicationThread()
2007 public Instrumentation getInstrumentation()
2009 return mInstrumentation;
2012 public boolean isProfiling() {
2013 return mProfiler != null && mProfiler.profileFile != null
2014 && mProfiler.profileFd == null;
2017 public String getProfileFilePath() {
2018 return mProfiler.profileFile;
2021 public Looper getLooper() {
2025 public Application getApplication() {
2026 return mInitialApplication;
2029 public String getProcessName() {
2030 return mBoundApplication.processName;
2033 public ContextImpl getSystemContext() {
2034 synchronized (this) {
2035 if (mSystemContext == null) {
2036 mSystemContext = ContextImpl.createSystemContext(this);
2038 return mSystemContext;
2042 public void installSystemApplicationInfo(ApplicationInfo info, ClassLoader classLoader) {
2043 synchronized (this) {
2044 getSystemContext().installSystemApplicationInfo(info, classLoader);
2046 // give ourselves a default profiler
2047 mProfiler = new Profiler();
2051 void ensureJitEnabled() {
2054 dalvik.system.VMRuntime.getRuntime().startJitCompilation();
2058 void scheduleGcIdler() {
2059 if (!mGcIdlerScheduled) {
2060 mGcIdlerScheduled = true;
2061 Looper.myQueue().addIdleHandler(mGcIdler);
2063 mH.removeMessages(H.GC_WHEN_IDLE);
2066 void unscheduleGcIdler() {
2067 if (mGcIdlerScheduled) {
2068 mGcIdlerScheduled = false;
2069 Looper.myQueue().removeIdleHandler(mGcIdler);
2071 mH.removeMessages(H.GC_WHEN_IDLE);
2074 void doGcIfNeeded() {
2075 mGcIdlerScheduled = false;
2076 final long now = SystemClock.uptimeMillis();
2077 //Slog.i(TAG, "**** WE MIGHT WANT TO GC: then=" + Binder.getLastGcTime()
2078 // + "m now=" + now);
2079 if ((BinderInternal.getLastGcTime()+MIN_TIME_BETWEEN_GCS) < now) {
2080 //Slog.i(TAG, "**** WE DO, WE DO WANT TO GC!");
2081 BinderInternal.forceGc("bg");
2085 private static final String HEAP_FULL_COLUMN
2086 = "%13s %8s %8s %8s %8s %8s %8s %8s %8s %8s %8s";
2087 private static final String HEAP_COLUMN
2088 = "%13s %8s %8s %8s %8s %8s %8s %8s";
2089 private static final String ONE_COUNT_COLUMN = "%21s %8d";
2090 private static final String TWO_COUNT_COLUMNS = "%21s %8d %21s %8d";
2091 private static final String ONE_COUNT_COLUMN_HEADER = "%21s %8s";
2093 // Formatting for checkin service - update version if row format changes
2094 private static final int ACTIVITY_THREAD_CHECKIN_VERSION = 4;
2096 static void printRow(PrintWriter pw, String format, Object...objs) {
2097 pw.println(String.format(format, objs));
2100 public static void dumpMemInfoTable(PrintWriter pw, Debug.MemoryInfo memInfo, boolean checkin,
2101 boolean dumpFullInfo, boolean dumpDalvik, boolean dumpSummaryOnly,
2102 int pid, String processName,
2103 long nativeMax, long nativeAllocated, long nativeFree,
2104 long dalvikMax, long dalvikAllocated, long dalvikFree) {
2106 // For checkin, we print one long comma-separated list of values
2108 // NOTE: if you change anything significant below, also consider changing
2109 // ACTIVITY_THREAD_CHECKIN_VERSION.
2112 pw.print(ACTIVITY_THREAD_CHECKIN_VERSION); pw.print(',');
2113 pw.print(pid); pw.print(',');
2114 pw.print(processName); pw.print(',');
2117 pw.print(nativeMax); pw.print(',');
2118 pw.print(dalvikMax); pw.print(',');
2120 pw.print(nativeMax + dalvikMax); pw.print(',');
2122 // Heap info - allocated
2123 pw.print(nativeAllocated); pw.print(',');
2124 pw.print(dalvikAllocated); pw.print(',');
2126 pw.print(nativeAllocated + dalvikAllocated); pw.print(',');
2129 pw.print(nativeFree); pw.print(',');
2130 pw.print(dalvikFree); pw.print(',');
2132 pw.print(nativeFree + dalvikFree); pw.print(',');
2134 // Heap info - proportional set size
2135 pw.print(memInfo.nativePss); pw.print(',');
2136 pw.print(memInfo.dalvikPss); pw.print(',');
2137 pw.print(memInfo.otherPss); pw.print(',');
2138 pw.print(memInfo.getTotalPss()); pw.print(',');
2140 // Heap info - swappable set size
2141 pw.print(memInfo.nativeSwappablePss); pw.print(',');
2142 pw.print(memInfo.dalvikSwappablePss); pw.print(',');
2143 pw.print(memInfo.otherSwappablePss); pw.print(',');
2144 pw.print(memInfo.getTotalSwappablePss()); pw.print(',');
2146 // Heap info - shared dirty
2147 pw.print(memInfo.nativeSharedDirty); pw.print(',');
2148 pw.print(memInfo.dalvikSharedDirty); pw.print(',');
2149 pw.print(memInfo.otherSharedDirty); pw.print(',');
2150 pw.print(memInfo.getTotalSharedDirty()); pw.print(',');
2152 // Heap info - shared clean
2153 pw.print(memInfo.nativeSharedClean); pw.print(',');
2154 pw.print(memInfo.dalvikSharedClean); pw.print(',');
2155 pw.print(memInfo.otherSharedClean); pw.print(',');
2156 pw.print(memInfo.getTotalSharedClean()); pw.print(',');
2158 // Heap info - private Dirty
2159 pw.print(memInfo.nativePrivateDirty); pw.print(',');
2160 pw.print(memInfo.dalvikPrivateDirty); pw.print(',');
2161 pw.print(memInfo.otherPrivateDirty); pw.print(',');
2162 pw.print(memInfo.getTotalPrivateDirty()); pw.print(',');
2164 // Heap info - private Clean
2165 pw.print(memInfo.nativePrivateClean); pw.print(',');
2166 pw.print(memInfo.dalvikPrivateClean); pw.print(',');
2167 pw.print(memInfo.otherPrivateClean); pw.print(',');
2168 pw.print(memInfo.getTotalPrivateClean()); pw.print(',');
2170 // Heap info - swapped out
2171 pw.print(memInfo.nativeSwappedOut); pw.print(',');
2172 pw.print(memInfo.dalvikSwappedOut); pw.print(',');
2173 pw.print(memInfo.otherSwappedOut); pw.print(',');
2174 pw.print(memInfo.getTotalSwappedOut()); pw.print(',');
2176 // Heap info - swapped out pss
2177 if (memInfo.hasSwappedOutPss) {
2178 pw.print(memInfo.nativeSwappedOutPss); pw.print(',');
2179 pw.print(memInfo.dalvikSwappedOutPss); pw.print(',');
2180 pw.print(memInfo.otherSwappedOutPss); pw.print(',');
2181 pw.print(memInfo.getTotalSwappedOutPss()); pw.print(',');
2189 // Heap info - other areas
2190 for (int i=0; i<Debug.MemoryInfo.NUM_OTHER_STATS; i++) {
2191 pw.print(Debug.MemoryInfo.getOtherLabel(i)); pw.print(',');
2192 pw.print(memInfo.getOtherPss(i)); pw.print(',');
2193 pw.print(memInfo.getOtherSwappablePss(i)); pw.print(',');
2194 pw.print(memInfo.getOtherSharedDirty(i)); pw.print(',');
2195 pw.print(memInfo.getOtherSharedClean(i)); pw.print(',');
2196 pw.print(memInfo.getOtherPrivateDirty(i)); pw.print(',');
2197 pw.print(memInfo.getOtherPrivateClean(i)); pw.print(',');
2198 pw.print(memInfo.getOtherSwappedOut(i)); pw.print(',');
2199 if (memInfo.hasSwappedOutPss) {
2200 pw.print(memInfo.getOtherSwappedOutPss(i)); pw.print(',');
2208 if (!dumpSummaryOnly) {
2210 printRow(pw, HEAP_FULL_COLUMN, "", "Pss", "Pss", "Shared", "Private",
2211 "Shared", "Private", memInfo.hasSwappedOutPss ? "SwapPss" : "Swap",
2212 "Heap", "Heap", "Heap");
2213 printRow(pw, HEAP_FULL_COLUMN, "", "Total", "Clean", "Dirty", "Dirty",
2214 "Clean", "Clean", "Dirty",
2215 "Size", "Alloc", "Free");
2216 printRow(pw, HEAP_FULL_COLUMN, "", "------", "------", "------", "------",
2217 "------", "------", "------", "------", "------", "------");
2218 printRow(pw, HEAP_FULL_COLUMN, "Native Heap", memInfo.nativePss,
2219 memInfo.nativeSwappablePss, memInfo.nativeSharedDirty,
2220 memInfo.nativePrivateDirty, memInfo.nativeSharedClean,
2221 memInfo.nativePrivateClean, memInfo.hasSwappedOutPss ?
2222 memInfo.nativeSwappedOut : memInfo.nativeSwappedOutPss,
2223 nativeMax, nativeAllocated, nativeFree);
2224 printRow(pw, HEAP_FULL_COLUMN, "Dalvik Heap", memInfo.dalvikPss,
2225 memInfo.dalvikSwappablePss, memInfo.dalvikSharedDirty,
2226 memInfo.dalvikPrivateDirty, memInfo.dalvikSharedClean,
2227 memInfo.dalvikPrivateClean, memInfo.hasSwappedOutPss ?
2228 memInfo.dalvikSwappedOut : memInfo.dalvikSwappedOutPss,
2229 dalvikMax, dalvikAllocated, dalvikFree);
2231 printRow(pw, HEAP_COLUMN, "", "Pss", "Private",
2232 "Private", memInfo.hasSwappedOutPss ? "SwapPss" : "Swap",
2233 "Heap", "Heap", "Heap");
2234 printRow(pw, HEAP_COLUMN, "", "Total", "Dirty",
2235 "Clean", "Dirty", "Size", "Alloc", "Free");
2236 printRow(pw, HEAP_COLUMN, "", "------", "------", "------",
2237 "------", "------", "------", "------", "------");
2238 printRow(pw, HEAP_COLUMN, "Native Heap", memInfo.nativePss,
2239 memInfo.nativePrivateDirty,
2240 memInfo.nativePrivateClean,
2241 memInfo.hasSwappedOutPss ? memInfo.nativeSwappedOutPss :
2242 memInfo.nativeSwappedOut,
2243 nativeMax, nativeAllocated, nativeFree);
2244 printRow(pw, HEAP_COLUMN, "Dalvik Heap", memInfo.dalvikPss,
2245 memInfo.dalvikPrivateDirty,
2246 memInfo.dalvikPrivateClean,
2247 memInfo.hasSwappedOutPss ? memInfo.dalvikSwappedOutPss :
2248 memInfo.dalvikSwappedOut,
2249 dalvikMax, dalvikAllocated, dalvikFree);
2252 int otherPss = memInfo.otherPss;
2253 int otherSwappablePss = memInfo.otherSwappablePss;
2254 int otherSharedDirty = memInfo.otherSharedDirty;
2255 int otherPrivateDirty = memInfo.otherPrivateDirty;
2256 int otherSharedClean = memInfo.otherSharedClean;
2257 int otherPrivateClean = memInfo.otherPrivateClean;
2258 int otherSwappedOut = memInfo.otherSwappedOut;
2259 int otherSwappedOutPss = memInfo.otherSwappedOutPss;
2261 for (int i=0; i<Debug.MemoryInfo.NUM_OTHER_STATS; i++) {
2262 final int myPss = memInfo.getOtherPss(i);
2263 final int mySwappablePss = memInfo.getOtherSwappablePss(i);
2264 final int mySharedDirty = memInfo.getOtherSharedDirty(i);
2265 final int myPrivateDirty = memInfo.getOtherPrivateDirty(i);
2266 final int mySharedClean = memInfo.getOtherSharedClean(i);
2267 final int myPrivateClean = memInfo.getOtherPrivateClean(i);
2268 final int mySwappedOut = memInfo.getOtherSwappedOut(i);
2269 final int mySwappedOutPss = memInfo.getOtherSwappedOutPss(i);
2270 if (myPss != 0 || mySharedDirty != 0 || myPrivateDirty != 0
2271 || mySharedClean != 0 || myPrivateClean != 0
2272 || (memInfo.hasSwappedOutPss ? mySwappedOutPss : mySwappedOut) != 0) {
2274 printRow(pw, HEAP_FULL_COLUMN, Debug.MemoryInfo.getOtherLabel(i),
2275 myPss, mySwappablePss, mySharedDirty, myPrivateDirty,
2276 mySharedClean, myPrivateClean,
2277 memInfo.hasSwappedOutPss ? mySwappedOutPss : mySwappedOut,
2280 printRow(pw, HEAP_COLUMN, Debug.MemoryInfo.getOtherLabel(i),
2281 myPss, myPrivateDirty,
2283 memInfo.hasSwappedOutPss ? mySwappedOutPss : mySwappedOut,
2287 otherSwappablePss -= mySwappablePss;
2288 otherSharedDirty -= mySharedDirty;
2289 otherPrivateDirty -= myPrivateDirty;
2290 otherSharedClean -= mySharedClean;
2291 otherPrivateClean -= myPrivateClean;
2292 otherSwappedOut -= mySwappedOut;
2293 otherSwappedOutPss -= mySwappedOutPss;
2298 printRow(pw, HEAP_FULL_COLUMN, "Unknown", otherPss, otherSwappablePss,
2299 otherSharedDirty, otherPrivateDirty, otherSharedClean, otherPrivateClean,
2300 memInfo.hasSwappedOutPss ? otherSwappedOutPss : otherSwappedOut,
2302 printRow(pw, HEAP_FULL_COLUMN, "TOTAL", memInfo.getTotalPss(),
2303 memInfo.getTotalSwappablePss(),
2304 memInfo.getTotalSharedDirty(), memInfo.getTotalPrivateDirty(),
2305 memInfo.getTotalSharedClean(), memInfo.getTotalPrivateClean(),
2306 memInfo.hasSwappedOutPss ? memInfo.getTotalSwappedOutPss() :
2307 memInfo.getTotalSwappedOut(),
2308 nativeMax+dalvikMax, nativeAllocated+dalvikAllocated,
2309 nativeFree+dalvikFree);
2311 printRow(pw, HEAP_COLUMN, "Unknown", otherPss,
2312 otherPrivateDirty, otherPrivateClean,
2313 memInfo.hasSwappedOutPss ? otherSwappedOutPss : otherSwappedOut,
2315 printRow(pw, HEAP_COLUMN, "TOTAL", memInfo.getTotalPss(),
2316 memInfo.getTotalPrivateDirty(),
2317 memInfo.getTotalPrivateClean(),
2318 memInfo.hasSwappedOutPss ? memInfo.getTotalSwappedOutPss() :
2319 memInfo.getTotalSwappedOut(),
2320 nativeMax+dalvikMax,
2321 nativeAllocated+dalvikAllocated, nativeFree+dalvikFree);
2326 pw.println(" Dalvik Details");
2328 for (int i=Debug.MemoryInfo.NUM_OTHER_STATS;
2329 i<Debug.MemoryInfo.NUM_OTHER_STATS + Debug.MemoryInfo.NUM_DVK_STATS; i++) {
2330 final int myPss = memInfo.getOtherPss(i);
2331 final int mySwappablePss = memInfo.getOtherSwappablePss(i);
2332 final int mySharedDirty = memInfo.getOtherSharedDirty(i);
2333 final int myPrivateDirty = memInfo.getOtherPrivateDirty(i);
2334 final int mySharedClean = memInfo.getOtherSharedClean(i);
2335 final int myPrivateClean = memInfo.getOtherPrivateClean(i);
2336 final int mySwappedOut = memInfo.getOtherSwappedOut(i);
2337 final int mySwappedOutPss = memInfo.getOtherSwappedOutPss(i);
2338 if (myPss != 0 || mySharedDirty != 0 || myPrivateDirty != 0
2339 || mySharedClean != 0 || myPrivateClean != 0
2340 || (memInfo.hasSwappedOutPss ? mySwappedOutPss : mySwappedOut) != 0) {
2342 printRow(pw, HEAP_FULL_COLUMN, Debug.MemoryInfo.getOtherLabel(i),
2343 myPss, mySwappablePss, mySharedDirty, myPrivateDirty,
2344 mySharedClean, myPrivateClean,
2345 memInfo.hasSwappedOutPss ? mySwappedOutPss : mySwappedOut,
2348 printRow(pw, HEAP_COLUMN, Debug.MemoryInfo.getOtherLabel(i),
2349 myPss, myPrivateDirty,
2351 memInfo.hasSwappedOutPss ? mySwappedOutPss : mySwappedOut,
2360 pw.println(" App Summary");
2361 printRow(pw, ONE_COUNT_COLUMN_HEADER, "", "Pss(KB)");
2362 printRow(pw, ONE_COUNT_COLUMN_HEADER, "", "------");
2363 printRow(pw, ONE_COUNT_COLUMN,
2364 "Java Heap:", memInfo.getSummaryJavaHeap());
2365 printRow(pw, ONE_COUNT_COLUMN,
2366 "Native Heap:", memInfo.getSummaryNativeHeap());
2367 printRow(pw, ONE_COUNT_COLUMN,
2368 "Code:", memInfo.getSummaryCode());
2369 printRow(pw, ONE_COUNT_COLUMN,
2370 "Stack:", memInfo.getSummaryStack());
2371 printRow(pw, ONE_COUNT_COLUMN,
2372 "Graphics:", memInfo.getSummaryGraphics());
2373 printRow(pw, ONE_COUNT_COLUMN,
2374 "Private Other:", memInfo.getSummaryPrivateOther());
2375 printRow(pw, ONE_COUNT_COLUMN,
2376 "System:", memInfo.getSummarySystem());
2378 if (memInfo.hasSwappedOutPss) {
2379 printRow(pw, TWO_COUNT_COLUMNS,
2380 "TOTAL:", memInfo.getSummaryTotalPss(),
2381 "TOTAL SWAP PSS:", memInfo.getSummaryTotalSwapPss());
2383 printRow(pw, TWO_COUNT_COLUMNS,
2384 "TOTAL:", memInfo.getSummaryTotalPss(),
2385 "TOTAL SWAP (KB):", memInfo.getSummaryTotalSwap());
2389 public void registerOnActivityPausedListener(Activity activity,
2390 OnActivityPausedListener listener) {
2391 synchronized (mOnPauseListeners) {
2392 ArrayList<OnActivityPausedListener> list = mOnPauseListeners.get(activity);
2394 list = new ArrayList<OnActivityPausedListener>();
2395 mOnPauseListeners.put(activity, list);
2401 public void unregisterOnActivityPausedListener(Activity activity,
2402 OnActivityPausedListener listener) {
2403 synchronized (mOnPauseListeners) {
2404 ArrayList<OnActivityPausedListener> list = mOnPauseListeners.get(activity);
2406 list.remove(listener);
2411 public final ActivityInfo resolveActivityInfo(Intent intent) {
2412 ActivityInfo aInfo = intent.resolveActivityInfo(
2413 mInitialApplication.getPackageManager(), PackageManager.GET_SHARED_LIBRARY_FILES);
2414 if (aInfo == null) {
2415 // Throw an exception.
2416 Instrumentation.checkStartActivityResult(
2417 ActivityManager.START_CLASS_NOT_FOUND, intent);
2422 public final Activity startActivityNow(Activity parent, String id,
2423 Intent intent, ActivityInfo activityInfo, IBinder token, Bundle state,
2424 Activity.NonConfigurationInstances lastNonConfigurationInstances) {
2425 ActivityClientRecord r = new ActivityClientRecord();
2432 r.activityInfo = activityInfo;
2433 r.lastNonConfigurationInstances = lastNonConfigurationInstances;
2435 ComponentName compname = intent.getComponent();
2437 if (compname != null) {
2438 name = compname.toShortString();
2440 name = "(Intent " + intent + ").getComponent() returned null";
2442 Slog.v(TAG, "Performing launch: action=" + intent.getAction()
2444 + ", token=" + token);
2446 return performLaunchActivity(r, null);
2449 public final Activity getActivity(IBinder token) {
2450 return mActivities.get(token).activity;
2453 public final void sendActivityResult(
2454 IBinder token, String id, int requestCode,
2455 int resultCode, Intent data) {
2456 if (DEBUG_RESULTS) Slog.v(TAG, "sendActivityResult: id=" + id
2457 + " req=" + requestCode + " res=" + resultCode + " data=" + data);
2458 ArrayList<ResultInfo> list = new ArrayList<ResultInfo>();
2459 list.add(new ResultInfo(id, requestCode, resultCode, data));
2460 mAppThread.scheduleSendResult(token, list);
2463 private void sendMessage(int what, Object obj) {
2464 sendMessage(what, obj, 0, 0, false);
2467 private void sendMessage(int what, Object obj, int arg1) {
2468 sendMessage(what, obj, arg1, 0, false);
2471 private void sendMessage(int what, Object obj, int arg1, int arg2) {
2472 sendMessage(what, obj, arg1, arg2, false);
2475 private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
2476 if (DEBUG_MESSAGES) Slog.v(
2477 TAG, "SCHEDULE " + what + " " + mH.codeToString(what)
2478 + ": " + arg1 + " / " + obj);
2479 Message msg = Message.obtain();
2485 msg.setAsynchronous(true);
2487 mH.sendMessage(msg);
2490 private void sendMessage(int what, Object obj, int arg1, int arg2, int seq) {
2491 if (DEBUG_MESSAGES) Slog.v(
2492 TAG, "SCHEDULE " + mH.codeToString(what) + " arg1=" + arg1 + " arg2=" + arg2 +
2494 Message msg = Message.obtain();
2496 SomeArgs args = SomeArgs.obtain();
2502 mH.sendMessage(msg);
2505 final void scheduleContextCleanup(ContextImpl context, String who,
2507 ContextCleanupInfo cci = new ContextCleanupInfo();
2508 cci.context = context;
2511 sendMessage(H.CLEAN_UP_CONTEXT, cci);
2514 private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
2515 // System.out.println("##### [" + System.currentTimeMillis() + "] ActivityThread.performLaunchActivity(" + r + ")");
2517 ActivityInfo aInfo = r.activityInfo;
2518 if (r.packageInfo == null) {
2519 r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
2520 Context.CONTEXT_INCLUDE_CODE);
2523 ComponentName component = r.intent.getComponent();
2524 if (component == null) {
2525 component = r.intent.resolveActivity(
2526 mInitialApplication.getPackageManager());
2527 r.intent.setComponent(component);
2530 if (r.activityInfo.targetActivity != null) {
2531 component = new ComponentName(r.activityInfo.packageName,
2532 r.activityInfo.targetActivity);
2535 Activity activity = null;
2537 java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
2538 activity = mInstrumentation.newActivity(
2539 cl, component.getClassName(), r.intent);
2540 StrictMode.incrementExpectedActivityCount(activity.getClass());
2541 r.intent.setExtrasClassLoader(cl);
2542 r.intent.prepareToEnterProcess();
2543 if (r.state != null) {
2544 r.state.setClassLoader(cl);
2546 } catch (Exception e) {
2547 if (!mInstrumentation.onException(activity, e)) {
2548 throw new RuntimeException(
2549 "Unable to instantiate activity " + component
2550 + ": " + e.toString(), e);
2555 Application app = r.packageInfo.makeApplication(false, mInstrumentation);
2557 if (localLOGV) Slog.v(TAG, "Performing launch of " + r);
2558 if (localLOGV) Slog.v(
2559 TAG, r + ": app=" + app
2560 + ", appName=" + app.getPackageName()
2561 + ", pkg=" + r.packageInfo.getPackageName()
2562 + ", comp=" + r.intent.getComponent().toShortString()
2563 + ", dir=" + r.packageInfo.getAppDir());
2565 if (activity != null) {
2566 Context appContext = createBaseContextForActivity(r, activity);
2567 CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
2568 Configuration config = new Configuration(mCompatConfiguration);
2569 if (r.overrideConfig != null) {
2570 config.updateFrom(r.overrideConfig);
2572 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "
2573 + r.activityInfo.name + " with config " + config);
2574 Window window = null;
2575 if (r.mPendingRemoveWindow != null && r.mPreserveWindow) {
2576 window = r.mPendingRemoveWindow;
2577 r.mPendingRemoveWindow = null;
2578 r.mPendingRemoveWindowManager = null;
2580 activity.attach(appContext, this, getInstrumentation(), r.token,
2581 r.ident, app, r.intent, r.activityInfo, title, r.parent,
2582 r.embeddedID, r.lastNonConfigurationInstances, config,
2583 r.referrer, r.voiceInteractor, window);
2585 if (customIntent != null) {
2586 activity.mIntent = customIntent;
2588 r.lastNonConfigurationInstances = null;
2589 activity.mStartedActivity = false;
2590 int theme = r.activityInfo.getThemeResource();
2592 activity.setTheme(theme);
2595 activity.mCalled = false;
2596 if (r.isPersistable()) {
2597 mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
2599 mInstrumentation.callActivityOnCreate(activity, r.state);
2601 if (!activity.mCalled) {
2602 throw new SuperNotCalledException(
2603 "Activity " + r.intent.getComponent().toShortString() +
2604 " did not call through to super.onCreate()");
2606 r.activity = activity;
2608 if (!r.activity.mFinished) {
2609 activity.performStart();
2612 if (!r.activity.mFinished) {
2613 if (r.isPersistable()) {
2614 if (r.state != null || r.persistentState != null) {
2615 mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state,
2618 } else if (r.state != null) {
2619 mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
2622 if (!r.activity.mFinished) {
2623 activity.mCalled = false;
2624 if (r.isPersistable()) {
2625 mInstrumentation.callActivityOnPostCreate(activity, r.state,
2628 mInstrumentation.callActivityOnPostCreate(activity, r.state);
2630 if (!activity.mCalled) {
2631 throw new SuperNotCalledException(
2632 "Activity " + r.intent.getComponent().toShortString() +
2633 " did not call through to super.onPostCreate()");
2639 mActivities.put(r.token, r);
2641 } catch (SuperNotCalledException e) {
2644 } catch (Exception e) {
2645 if (!mInstrumentation.onException(activity, e)) {
2646 throw new RuntimeException(
2647 "Unable to start activity " + component
2648 + ": " + e.toString(), e);
2655 private Context createBaseContextForActivity(ActivityClientRecord r, final Activity activity) {
2656 int displayId = Display.DEFAULT_DISPLAY;
2658 displayId = ActivityManagerNative.getDefault().getActivityDisplayId(r.token);
2659 } catch (RemoteException e) {
2660 throw e.rethrowFromSystemServer();
2663 ContextImpl appContext = ContextImpl.createActivityContext(
2664 this, r.packageInfo, r.token, displayId, r.overrideConfig);
2665 appContext.setOuterContext(activity);
2666 Context baseContext = appContext;
2668 final DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance();
2669 // For debugging purposes, if the activity's package name contains the value of
2670 // the "debug.use-second-display" system property as a substring, then show
2671 // its content on a secondary display if there is one.
2672 String pkgName = SystemProperties.get("debug.second-display.pkg");
2673 if (pkgName != null && !pkgName.isEmpty()
2674 && r.packageInfo.mPackageName.contains(pkgName)) {
2675 for (int id : dm.getDisplayIds()) {
2676 if (id != Display.DEFAULT_DISPLAY) {
2678 dm.getCompatibleDisplay(id, appContext.getDisplayAdjustments(id));
2679 baseContext = appContext.createDisplayContext(display);
2687 private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
2688 // If we are getting ready to gc after going to the background, well
2689 // we are back active so skip it.
2690 unscheduleGcIdler();
2691 mSomeActivitiesChanged = true;
2693 if (r.profilerInfo != null) {
2694 mProfiler.setProfiler(r.profilerInfo);
2695 mProfiler.startProfiling();
2698 // Make sure we are running with the most recent config.
2699 handleConfigurationChanged(null, null);
2701 if (localLOGV) Slog.v(
2702 TAG, "Handling launch of " + r);
2704 // Initialize before creating the activity
2705 WindowManagerGlobal.initialize();
2707 Activity a = performLaunchActivity(r, customIntent);
2710 r.createdConfig = new Configuration(mConfiguration);
2711 reportSizeConfigurations(r);
2712 Bundle oldState = r.state;
2713 handleResumeActivity(r.token, false, r.isForward,
2714 !r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);
2716 if (!r.activity.mFinished && r.startsNotResumed) {
2717 // The activity manager actually wants this one to start out paused, because it
2718 // needs to be visible but isn't in the foreground. We accomplish this by going
2719 // through the normal startup (because activities expect to go through onResume()
2720 // the first time they run, before their window is displayed), and then pausing it.
2721 // However, in this case we do -not- need to do the full pause cycle (of freezing
2722 // and such) because the activity manager assumes it can just retain the current
2724 performPauseActivityIfNeeded(r, reason);
2726 // We need to keep around the original state, in case we need to be created again.
2727 // But we only do this for pre-Honeycomb apps, which always save their state when
2728 // pausing, so we can not have them save their state when restarting from a paused
2729 // state. For HC and later, we want to (and can) let the state be saved as the
2730 // normal part of stopping the activity.
2731 if (r.isPreHoneycomb()) {
2736 // If there was an error, for any reason, tell the activity manager to stop us.
2738 ActivityManagerNative.getDefault()
2739 .finishActivity(r.token, Activity.RESULT_CANCELED, null,
2740 Activity.DONT_FINISH_TASK_WITH_ACTIVITY);
2741 } catch (RemoteException ex) {
2742 throw ex.rethrowFromSystemServer();
2747 private void reportSizeConfigurations(ActivityClientRecord r) {
2748 Configuration[] configurations = r.activity.getResources().getSizeConfigurations();
2749 if (configurations == null) {
2752 SparseIntArray horizontal = new SparseIntArray();
2753 SparseIntArray vertical = new SparseIntArray();
2754 SparseIntArray smallest = new SparseIntArray();
2755 for (int i = configurations.length - 1; i >= 0; i--) {
2756 Configuration config = configurations[i];
2757 if (config.screenHeightDp != Configuration.SCREEN_HEIGHT_DP_UNDEFINED) {
2758 vertical.put(config.screenHeightDp, 0);
2760 if (config.screenWidthDp != Configuration.SCREEN_WIDTH_DP_UNDEFINED) {
2761 horizontal.put(config.screenWidthDp, 0);
2763 if (config.smallestScreenWidthDp != Configuration.SMALLEST_SCREEN_WIDTH_DP_UNDEFINED) {
2764 smallest.put(config.smallestScreenWidthDp, 0);
2768 ActivityManagerNative.getDefault().reportSizeConfigurations(r.token,
2769 horizontal.copyKeys(), vertical.copyKeys(), smallest.copyKeys());
2770 } catch (RemoteException ex) {
2771 throw ex.rethrowFromSystemServer();
2776 private void deliverNewIntents(ActivityClientRecord r, List<ReferrerIntent> intents) {
2777 final int N = intents.size();
2778 for (int i=0; i<N; i++) {
2779 ReferrerIntent intent = intents.get(i);
2780 intent.setExtrasClassLoader(r.activity.getClassLoader());
2781 intent.prepareToEnterProcess();
2782 r.activity.mFragments.noteStateNotSaved();
2783 mInstrumentation.callActivityOnNewIntent(r.activity, intent);
2787 public final void performNewIntents(IBinder token, List<ReferrerIntent> intents) {
2788 ActivityClientRecord r = mActivities.get(token);
2790 final boolean resumed = !r.paused;
2792 r.activity.mTemporaryPause = true;
2793 mInstrumentation.callActivityOnPause(r.activity);
2795 deliverNewIntents(r, intents);
2797 r.activity.performResume();
2798 r.activity.mTemporaryPause = false;
2803 private void handleNewIntent(NewIntentData data) {
2804 performNewIntents(data.token, data.intents);
2807 public void handleRequestAssistContextExtras(RequestAssistContextExtras cmd) {
2808 if (mLastSessionId != cmd.sessionId) {
2809 // Clear the existing structures
2810 mLastSessionId = cmd.sessionId;
2811 for (int i = mLastAssistStructures.size() - 1; i >= 0; i--) {
2812 AssistStructure structure = mLastAssistStructures.get(i).get();
2813 if (structure != null) {
2814 structure.clearSendChannel();
2816 mLastAssistStructures.remove(i);
2819 Bundle data = new Bundle();
2820 AssistStructure structure = null;
2821 AssistContent content = new AssistContent();
2822 ActivityClientRecord r = mActivities.get(cmd.activityToken);
2823 Uri referrer = null;
2825 r.activity.getApplication().dispatchOnProvideAssistData(r.activity, data);
2826 r.activity.onProvideAssistData(data);
2827 referrer = r.activity.onProvideReferrer();
2828 if (cmd.requestType == ActivityManager.ASSIST_CONTEXT_FULL) {
2829 structure = new AssistStructure(r.activity);
2830 Intent activityIntent = r.activity.getIntent();
2831 if (activityIntent != null && (r.window == null ||
2832 (r.window.getAttributes().flags
2833 & WindowManager.LayoutParams.FLAG_SECURE) == 0)) {
2834 Intent intent = new Intent(activityIntent);
2835 intent.setFlags(intent.getFlags() & ~(Intent.FLAG_GRANT_WRITE_URI_PERMISSION
2836 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION));
2837 intent.removeUnsafeExtras();
2838 content.setDefaultIntent(intent);
2840 content.setDefaultIntent(new Intent());
2842 r.activity.onProvideAssistContent(content);
2845 if (structure == null) {
2846 structure = new AssistStructure();
2848 mLastAssistStructures.add(new WeakReference<>(structure));
2849 IActivityManager mgr = ActivityManagerNative.getDefault();
2851 mgr.reportAssistContextExtras(cmd.requestToken, data, structure, content, referrer);
2852 } catch (RemoteException e) {
2853 throw e.rethrowFromSystemServer();
2857 public void handleTranslucentConversionComplete(IBinder token, boolean drawComplete) {
2858 ActivityClientRecord r = mActivities.get(token);
2860 r.activity.onTranslucentConversionComplete(drawComplete);
2864 public void onNewActivityOptions(IBinder token, ActivityOptions options) {
2865 ActivityClientRecord r = mActivities.get(token);
2867 r.activity.onNewActivityOptions(options);
2871 public void handleCancelVisibleBehind(IBinder token) {
2872 ActivityClientRecord r = mActivities.get(token);
2874 mSomeActivitiesChanged = true;
2875 final Activity activity = r.activity;
2876 if (activity.mVisibleBehind) {
2877 activity.mCalled = false;
2878 activity.onVisibleBehindCanceled();
2879 // Tick, tick, tick. The activity has 500 msec to return or it will be destroyed.
2880 if (!activity.mCalled) {
2881 throw new SuperNotCalledException("Activity " + activity.getLocalClassName() +
2882 " did not call through to super.onVisibleBehindCanceled()");
2884 activity.mVisibleBehind = false;
2888 ActivityManagerNative.getDefault().backgroundResourcesReleased(token);
2889 } catch (RemoteException e) {
2890 throw e.rethrowFromSystemServer();
2894 public void handleOnBackgroundVisibleBehindChanged(IBinder token, boolean visible) {
2895 ActivityClientRecord r = mActivities.get(token);
2897 r.activity.onBackgroundVisibleBehindChanged(visible);
2901 public void handleInstallProvider(ProviderInfo info) {
2902 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
2904 installContentProviders(mInitialApplication, Lists.newArrayList(info));
2906 StrictMode.setThreadPolicy(oldPolicy);
2910 private void handleEnterAnimationComplete(IBinder token) {
2911 ActivityClientRecord r = mActivities.get(token);
2913 r.activity.dispatchEnterAnimationComplete();
2917 private void handleStartBinderTracking() {
2918 Binder.enableTracing();
2921 private void handleStopBinderTrackingAndDump(ParcelFileDescriptor fd) {
2923 Binder.disableTracing();
2924 Binder.getTransactionTracker().writeTracesToFile(fd);
2926 IoUtils.closeQuietly(fd);
2927 Binder.getTransactionTracker().clearTraces();
2931 private void handleMultiWindowModeChanged(IBinder token, boolean isInMultiWindowMode) {
2932 final ActivityClientRecord r = mActivities.get(token);
2934 r.activity.dispatchMultiWindowModeChanged(isInMultiWindowMode);
2938 private void handlePictureInPictureModeChanged(IBinder token, boolean isInPipMode) {
2939 final ActivityClientRecord r = mActivities.get(token);
2941 r.activity.dispatchPictureInPictureModeChanged(isInPipMode);
2945 private void handleLocalVoiceInteractionStarted(IBinder token, IVoiceInteractor interactor) {
2946 final ActivityClientRecord r = mActivities.get(token);
2948 r.voiceInteractor = interactor;
2949 r.activity.setVoiceInteractor(interactor);
2950 if (interactor == null) {
2951 r.activity.onLocalVoiceInteractionStopped();
2953 r.activity.onLocalVoiceInteractionStarted();
2958 private static final ThreadLocal<Intent> sCurrentBroadcastIntent = new ThreadLocal<Intent>();
2961 * Return the Intent that's currently being handled by a
2962 * BroadcastReceiver on this thread, or null if none.
2965 public static Intent getIntentBeingBroadcast() {
2966 return sCurrentBroadcastIntent.get();
2969 private void handleReceiver(ReceiverData data) {
2970 // If we are getting ready to gc after going to the background, well
2971 // we are back active so skip it.
2972 unscheduleGcIdler();
2974 String component = data.intent.getComponent().getClassName();
2976 LoadedApk packageInfo = getPackageInfoNoCheck(
2977 data.info.applicationInfo, data.compatInfo);
2979 IActivityManager mgr = ActivityManagerNative.getDefault();
2981 BroadcastReceiver receiver;
2983 java.lang.ClassLoader cl = packageInfo.getClassLoader();
2984 data.intent.setExtrasClassLoader(cl);
2985 data.intent.prepareToEnterProcess();
2986 data.setExtrasClassLoader(cl);
2987 receiver = (BroadcastReceiver)cl.loadClass(component).newInstance();
2988 } catch (Exception e) {
2989 if (DEBUG_BROADCAST) Slog.i(TAG,
2990 "Finishing failed broadcast to " + data.intent.getComponent());
2991 data.sendFinished(mgr);
2992 throw new RuntimeException(
2993 "Unable to instantiate receiver " + component
2994 + ": " + e.toString(), e);
2998 Application app = packageInfo.makeApplication(false, mInstrumentation);
3000 if (localLOGV) Slog.v(
3001 TAG, "Performing receive of " + data.intent
3003 + ", appName=" + app.getPackageName()
3004 + ", pkg=" + packageInfo.getPackageName()
3005 + ", comp=" + data.intent.getComponent().toShortString()
3006 + ", dir=" + packageInfo.getAppDir());
3008 ContextImpl context = (ContextImpl)app.getBaseContext();
3009 sCurrentBroadcastIntent.set(data.intent);
3010 receiver.setPendingResult(data);
3011 receiver.onReceive(context.getReceiverRestrictedContext(),
3013 } catch (Exception e) {
3014 if (DEBUG_BROADCAST) Slog.i(TAG,
3015 "Finishing failed broadcast to " + data.intent.getComponent());
3016 data.sendFinished(mgr);
3017 if (!mInstrumentation.onException(receiver, e)) {
3018 throw new RuntimeException(
3019 "Unable to start receiver " + component
3020 + ": " + e.toString(), e);
3023 sCurrentBroadcastIntent.set(null);
3026 if (receiver.getPendingResult() != null) {
3031 // Instantiate a BackupAgent and tell it that it's alive
3032 private void handleCreateBackupAgent(CreateBackupAgentData data) {
3033 if (DEBUG_BACKUP) Slog.v(TAG, "handleCreateBackupAgent: " + data);
3035 // Sanity check the requested target package's uid against ours
3037 PackageInfo requestedPackage = getPackageManager().getPackageInfo(
3038 data.appInfo.packageName, 0, UserHandle.myUserId());
3039 if (requestedPackage.applicationInfo.uid != Process.myUid()) {
3040 Slog.w(TAG, "Asked to instantiate non-matching package "
3041 + data.appInfo.packageName);
3044 } catch (RemoteException e) {
3045 throw e.rethrowFromSystemServer();
3048 // no longer idle; we have backup work to do
3049 unscheduleGcIdler();
3051 // instantiate the BackupAgent class named in the manifest
3052 LoadedApk packageInfo = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
3053 String packageName = packageInfo.mPackageName;
3054 if (packageName == null) {
3055 Slog.d(TAG, "Asked to create backup agent for nonexistent package");
3059 String classname = data.appInfo.backupAgentName;
3060 // full backup operation but no app-supplied agent? use the default implementation
3061 if (classname == null && (data.backupMode == IApplicationThread.BACKUP_MODE_FULL
3062 || data.backupMode == IApplicationThread.BACKUP_MODE_RESTORE_FULL)) {
3063 classname = "android.app.backup.FullBackupAgent";
3067 IBinder binder = null;
3068 BackupAgent agent = mBackupAgents.get(packageName);
3069 if (agent != null) {
3070 // reusing the existing instance
3072 Slog.v(TAG, "Reusing existing agent instance");
3074 binder = agent.onBind();
3077 if (DEBUG_BACKUP) Slog.v(TAG, "Initializing agent class " + classname);
3079 java.lang.ClassLoader cl = packageInfo.getClassLoader();
3080 agent = (BackupAgent) cl.loadClass(classname).newInstance();
3082 // set up the agent's context
3083 ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
3084 context.setOuterContext(agent);
3085 agent.attach(context);
3088 binder = agent.onBind();
3089 mBackupAgents.put(packageName, agent);
3090 } catch (Exception e) {
3091 // If this is during restore, fail silently; otherwise go
3092 // ahead and let the user see the crash.
3093 Slog.e(TAG, "Agent threw during creation: " + e);
3094 if (data.backupMode != IApplicationThread.BACKUP_MODE_RESTORE
3095 && data.backupMode != IApplicationThread.BACKUP_MODE_RESTORE_FULL) {
3098 // falling through with 'binder' still null
3102 // tell the OS that we're live now
3104 ActivityManagerNative.getDefault().backupAgentCreated(packageName, binder);
3105 } catch (RemoteException e) {
3106 throw e.rethrowFromSystemServer();
3108 } catch (Exception e) {
3109 throw new RuntimeException("Unable to create BackupAgent "
3110 + classname + ": " + e.toString(), e);
3114 // Tear down a BackupAgent
3115 private void handleDestroyBackupAgent(CreateBackupAgentData data) {
3116 if (DEBUG_BACKUP) Slog.v(TAG, "handleDestroyBackupAgent: " + data);
3118 LoadedApk packageInfo = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
3119 String packageName = packageInfo.mPackageName;
3120 BackupAgent agent = mBackupAgents.get(packageName);
3121 if (agent != null) {
3124 } catch (Exception e) {
3125 Slog.w(TAG, "Exception thrown in onDestroy by backup agent of " + data.appInfo);
3126 e.printStackTrace();
3128 mBackupAgents.remove(packageName);
3130 Slog.w(TAG, "Attempt to destroy unknown backup agent " + data);
3134 private void handleCreateService(CreateServiceData data) {
3135 // If we are getting ready to gc after going to the background, well
3136 // we are back active so skip it.
3137 unscheduleGcIdler();
3139 LoadedApk packageInfo = getPackageInfoNoCheck(
3140 data.info.applicationInfo, data.compatInfo);
3141 Service service = null;
3143 java.lang.ClassLoader cl = packageInfo.getClassLoader();
3144 service = (Service) cl.loadClass(data.info.name).newInstance();
3145 } catch (Exception e) {
3146 if (!mInstrumentation.onException(service, e)) {
3147 throw new RuntimeException(
3148 "Unable to instantiate service " + data.info.name
3149 + ": " + e.toString(), e);
3154 if (localLOGV) Slog.v(TAG, "Creating service " + data.info.name);
3156 ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
3157 context.setOuterContext(service);
3159 Application app = packageInfo.makeApplication(false, mInstrumentation);
3160 service.attach(context, this, data.info.name, data.token, app,
3161 ActivityManagerNative.getDefault());
3163 mServices.put(data.token, service);
3165 ActivityManagerNative.getDefault().serviceDoneExecuting(
3166 data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
3167 } catch (RemoteException e) {
3168 throw e.rethrowFromSystemServer();
3170 } catch (Exception e) {
3171 if (!mInstrumentation.onException(service, e)) {
3172 throw new RuntimeException(
3173 "Unable to create service " + data.info.name
3174 + ": " + e.toString(), e);
3179 private void handleBindService(BindServiceData data) {
3180 Service s = mServices.get(data.token);
3182 Slog.v(TAG, "handleBindService s=" + s + " rebind=" + data.rebind);
3185 data.intent.setExtrasClassLoader(s.getClassLoader());
3186 data.intent.prepareToEnterProcess();
3189 IBinder binder = s.onBind(data.intent);
3190 ActivityManagerNative.getDefault().publishService(
3191 data.token, data.intent, binder);
3193 s.onRebind(data.intent);
3194 ActivityManagerNative.getDefault().serviceDoneExecuting(
3195 data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
3198 } catch (RemoteException ex) {
3199 throw ex.rethrowFromSystemServer();
3201 } catch (Exception e) {
3202 if (!mInstrumentation.onException(s, e)) {
3203 throw new RuntimeException(
3204 "Unable to bind to service " + s
3205 + " with " + data.intent + ": " + e.toString(), e);
3211 private void handleUnbindService(BindServiceData data) {
3212 Service s = mServices.get(data.token);
3215 data.intent.setExtrasClassLoader(s.getClassLoader());
3216 data.intent.prepareToEnterProcess();
3217 boolean doRebind = s.onUnbind(data.intent);
3220 ActivityManagerNative.getDefault().unbindFinished(
3221 data.token, data.intent, doRebind);
3223 ActivityManagerNative.getDefault().serviceDoneExecuting(
3224 data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
3226 } catch (RemoteException ex) {
3227 throw ex.rethrowFromSystemServer();
3229 } catch (Exception e) {
3230 if (!mInstrumentation.onException(s, e)) {
3231 throw new RuntimeException(
3232 "Unable to unbind to service " + s
3233 + " with " + data.intent + ": " + e.toString(), e);
3239 private void handleDumpService(DumpComponentInfo info) {
3240 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
3242 Service s = mServices.get(info.token);
3244 PrintWriter pw = new FastPrintWriter(new FileOutputStream(
3245 info.fd.getFileDescriptor()));
3246 s.dump(info.fd.getFileDescriptor(), pw, info.args);
3250 IoUtils.closeQuietly(info.fd);
3251 StrictMode.setThreadPolicy(oldPolicy);
3255 private void handleDumpActivity(DumpComponentInfo info) {
3256 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
3258 ActivityClientRecord r = mActivities.get(info.token);
3259 if (r != null && r.activity != null) {
3260 PrintWriter pw = new FastPrintWriter(new FileOutputStream(
3261 info.fd.getFileDescriptor()));
3262 r.activity.dump(info.prefix, info.fd.getFileDescriptor(), pw, info.args);
3266 IoUtils.closeQuietly(info.fd);
3267 StrictMode.setThreadPolicy(oldPolicy);
3271 private void handleDumpProvider(DumpComponentInfo info) {
3272 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
3274 ProviderClientRecord r = mLocalProviders.get(info.token);
3275 if (r != null && r.mLocalProvider != null) {
3276 PrintWriter pw = new FastPrintWriter(new FileOutputStream(
3277 info.fd.getFileDescriptor()));
3278 r.mLocalProvider.dump(info.fd.getFileDescriptor(), pw, info.args);
3282 IoUtils.closeQuietly(info.fd);
3283 StrictMode.setThreadPolicy(oldPolicy);
3287 private void handleServiceArgs(ServiceArgsData data) {
3288 Service s = mServices.get(data.token);
3291 if (data.args != null) {
3292 data.args.setExtrasClassLoader(s.getClassLoader());
3293 data.args.prepareToEnterProcess();
3296 if (!data.taskRemoved) {
3297 res = s.onStartCommand(data.args, data.flags, data.startId);
3299 s.onTaskRemoved(data.args);
3300 res = Service.START_TASK_REMOVED_COMPLETE;
3303 QueuedWork.waitToFinish();
3306 ActivityManagerNative.getDefault().serviceDoneExecuting(
3307 data.token, SERVICE_DONE_EXECUTING_START, data.startId, res);
3308 } catch (RemoteException e) {
3309 throw e.rethrowFromSystemServer();
3312 } catch (Exception e) {
3313 if (!mInstrumentation.onException(s, e)) {
3314 throw new RuntimeException(
3315 "Unable to start service " + s
3316 + " with " + data.args + ": " + e.toString(), e);
3322 private void handleStopService(IBinder token) {
3323 Service s = mServices.remove(token);
3326 if (localLOGV) Slog.v(TAG, "Destroying service " + s);
3328 Context context = s.getBaseContext();
3329 if (context instanceof ContextImpl) {
3330 final String who = s.getClassName();
3331 ((ContextImpl) context).scheduleFinalCleanup(who, "Service");
3334 QueuedWork.waitToFinish();
3337 ActivityManagerNative.getDefault().serviceDoneExecuting(
3338 token, SERVICE_DONE_EXECUTING_STOP, 0, 0);
3339 } catch (RemoteException e) {
3340 throw e.rethrowFromSystemServer();
3342 } catch (Exception e) {
3343 if (!mInstrumentation.onException(s, e)) {
3344 throw new RuntimeException(
3345 "Unable to stop service " + s
3346 + ": " + e.toString(), e);
3348 Slog.i(TAG, "handleStopService: exception for " + token, e);
3351 Slog.i(TAG, "handleStopService: token=" + token + " not found.");
3353 //Slog.i(TAG, "Running services: " + mServices);
3356 public final ActivityClientRecord performResumeActivity(IBinder token,
3357 boolean clearHide, String reason) {
3358 ActivityClientRecord r = mActivities.get(token);
3359 if (localLOGV) Slog.v(TAG, "Performing resume of " + r
3360 + " finished=" + r.activity.mFinished);
3361 if (r != null && !r.activity.mFinished) {
3363 r.hideForNow = false;
3364 r.activity.mStartedActivity = false;
3367 r.activity.onStateNotSaved();
3368 r.activity.mFragments.noteStateNotSaved();
3369 if (r.pendingIntents != null) {
3370 deliverNewIntents(r, r.pendingIntents);
3371 r.pendingIntents = null;
3373 if (r.pendingResults != null) {
3374 deliverResults(r, r.pendingResults);
3375 r.pendingResults = null;
3377 r.activity.performResume();
3379 // If there is a pending local relaunch that was requested when the activity was
3380 // paused, it will put the activity into paused state when it finally happens.
3381 // Since the activity resumed before being relaunched, we don't want that to happen,
3382 // so we need to clear the request to relaunch paused.
3383 for (int i = mRelaunchingActivities.size() - 1; i >= 0; i--) {
3384 final ActivityClientRecord relaunching = mRelaunchingActivities.get(i);
3385 if (relaunching.token == r.token
3386 && relaunching.onlyLocalRequest && relaunching.startsNotResumed) {
3387 relaunching.startsNotResumed = false;
3391 EventLog.writeEvent(LOG_AM_ON_RESUME_CALLED, UserHandle.myUserId(),
3392 r.activity.getComponentName().getClassName(), reason);
3397 r.persistentState = null;
3398 } catch (Exception e) {
3399 if (!mInstrumentation.onException(r.activity, e)) {
3400 throw new RuntimeException(
3401 "Unable to resume activity "
3402 + r.intent.getComponent().toShortString()
3403 + ": " + e.toString(), e);
3410 static final void cleanUpPendingRemoveWindows(ActivityClientRecord r, boolean force) {
3411 if (r.mPreserveWindow && !force) {
3414 if (r.mPendingRemoveWindow != null) {
3415 r.mPendingRemoveWindowManager.removeViewImmediate(
3416 r.mPendingRemoveWindow.getDecorView());
3417 IBinder wtoken = r.mPendingRemoveWindow.getDecorView().getWindowToken();
3418 if (wtoken != null) {
3419 WindowManagerGlobal.getInstance().closeAll(wtoken,
3420 r.activity.getClass().getName(), "Activity");
3423 r.mPendingRemoveWindow = null;
3424 r.mPendingRemoveWindowManager = null;
3427 final void handleResumeActivity(IBinder token,
3428 boolean clearHide, boolean isForward, boolean reallyResume, int seq, String reason) {
3429 ActivityClientRecord r = mActivities.get(token);
3430 if (!checkAndUpdateLifecycleSeq(seq, r, "resumeActivity")) {
3434 // If we are getting ready to gc after going to the background, well
3435 // we are back active so skip it.
3436 unscheduleGcIdler();
3437 mSomeActivitiesChanged = true;
3439 // TODO Push resumeArgs into the activity for consideration
3440 r = performResumeActivity(token, clearHide, reason);
3443 final Activity a = r.activity;
3445 if (localLOGV) Slog.v(
3446 TAG, "Resume " + r + " started activity: " +
3447 a.mStartedActivity + ", hideForNow: " + r.hideForNow
3448 + ", finished: " + a.mFinished);
3450 final int forwardBit = isForward ?
3451 WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION : 0;
3453 // If the window hasn't yet been added to the window manager,
3454 // and this guy didn't finish itself or start another activity,
3455 // then go ahead and add the window.
3456 boolean willBeVisible = !a.mStartedActivity;
3457 if (!willBeVisible) {
3459 willBeVisible = ActivityManagerNative.getDefault().willActivityBeVisible(
3460 a.getActivityToken());
3461 } catch (RemoteException e) {
3462 throw e.rethrowFromSystemServer();
3465 if (r.window == null && !a.mFinished && willBeVisible) {
3466 r.window = r.activity.getWindow();
3467 View decor = r.window.getDecorView();
3468 decor.setVisibility(View.INVISIBLE);
3469 ViewManager wm = a.getWindowManager();
3470 WindowManager.LayoutParams l = r.window.getAttributes();
3472 l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
3473 l.softInputMode |= forwardBit;
3474 if (r.mPreserveWindow) {
3475 a.mWindowAdded = true;
3476 r.mPreserveWindow = false;
3477 // Normally the ViewRoot sets up callbacks with the Activity
3478 // in addView->ViewRootImpl#setView. If we are instead reusing
3479 // the decor view we have to notify the view root that the
3480 // callbacks may have changed.
3481 ViewRootImpl impl = decor.getViewRootImpl();
3483 impl.notifyChildRebuilt();
3486 if (a.mVisibleFromClient && !a.mWindowAdded) {
3487 a.mWindowAdded = true;
3488 wm.addView(decor, l);
3491 // If the window has already been added, but during resume
3492 // we started another activity, then don't yet make the
3494 } else if (!willBeVisible) {
3495 if (localLOGV) Slog.v(
3496 TAG, "Launch " + r + " mStartedActivity set");
3497 r.hideForNow = true;
3500 // Get rid of anything left hanging around.
3501 cleanUpPendingRemoveWindows(r, false /* force */);
3503 // The window is now visible if it has been added, we are not
3504 // simply finishing, and we are not starting another activity.
3505 if (!r.activity.mFinished && willBeVisible
3506 && r.activity.mDecor != null && !r.hideForNow) {
3507 if (r.newConfig != null) {
3508 performConfigurationChangedForActivity(r, r.newConfig, REPORT_TO_ACTIVITY);
3509 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Resuming activity "
3510 + r.activityInfo.name + " with newConfig " + r.activity.mCurrentConfig);
3513 if (localLOGV) Slog.v(TAG, "Resuming " + r + " with isForward="
3515 WindowManager.LayoutParams l = r.window.getAttributes();
3516 if ((l.softInputMode
3517 & WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION)
3519 l.softInputMode = (l.softInputMode
3520 & (~WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION))
3522 if (r.activity.mVisibleFromClient) {
3523 ViewManager wm = a.getWindowManager();
3524 View decor = r.window.getDecorView();
3525 wm.updateViewLayout(decor, l);
3528 r.activity.mVisibleFromServer = true;
3529 mNumVisibleActivities++;
3530 if (r.activity.mVisibleFromClient) {
3531 r.activity.makeVisible();
3535 if (!r.onlyLocalRequest) {
3536 r.nextIdle = mNewActivities;
3538 if (localLOGV) Slog.v(
3539 TAG, "Scheduling idle handler for " + r);
3540 Looper.myQueue().addIdleHandler(new Idler());
3542 r.onlyLocalRequest = false;
3544 // Tell the activity manager we have resumed.
3547 ActivityManagerNative.getDefault().activityResumed(token);
3548 } catch (RemoteException ex) {
3549 throw ex.rethrowFromSystemServer();
3554 // If an exception was thrown when trying to resume, then
3555 // just end this activity.
3557 ActivityManagerNative.getDefault()
3558 .finishActivity(token, Activity.RESULT_CANCELED, null,
3559 Activity.DONT_FINISH_TASK_WITH_ACTIVITY);
3560 } catch (RemoteException ex) {
3561 throw ex.rethrowFromSystemServer();
3566 private int mThumbnailWidth = -1;
3567 private int mThumbnailHeight = -1;
3568 private Bitmap mAvailThumbnailBitmap = null;
3569 private Canvas mThumbnailCanvas = null;
3571 private Bitmap createThumbnailBitmap(ActivityClientRecord r) {
3572 Bitmap thumbnail = mAvailThumbnailBitmap;
3574 if (thumbnail == null) {
3575 int w = mThumbnailWidth;
3578 Resources res = r.activity.getResources();
3579 int wId = com.android.internal.R.dimen.thumbnail_width;
3580 int hId = com.android.internal.R.dimen.thumbnail_height;
3581 mThumbnailWidth = w = res.getDimensionPixelSize(wId);
3582 mThumbnailHeight = h = res.getDimensionPixelSize(hId);
3584 h = mThumbnailHeight;
3587 // On platforms where we don't want thumbnails, set dims to (0,0)
3588 if ((w > 0) && (h > 0)) {
3589 thumbnail = Bitmap.createBitmap(r.activity.getResources().getDisplayMetrics(),
3590 w, h, THUMBNAIL_FORMAT);
3591 thumbnail.eraseColor(0);
3595 if (thumbnail != null) {
3596 Canvas cv = mThumbnailCanvas;
3598 mThumbnailCanvas = cv = new Canvas();
3601 cv.setBitmap(thumbnail);
3602 if (!r.activity.onCreateThumbnail(thumbnail, cv)) {
3603 mAvailThumbnailBitmap = thumbnail;
3609 } catch (Exception e) {
3610 if (!mInstrumentation.onException(r.activity, e)) {
3611 throw new RuntimeException(
3612 "Unable to create thumbnail of "
3613 + r.intent.getComponent().toShortString()
3614 + ": " + e.toString(), e);
3622 private void handlePauseActivity(IBinder token, boolean finished,
3623 boolean userLeaving, int configChanges, boolean dontReport, int seq) {
3624 ActivityClientRecord r = mActivities.get(token);
3625 if (DEBUG_ORDER) Slog.d(TAG, "handlePauseActivity " + r + ", seq: " + seq);
3626 if (!checkAndUpdateLifecycleSeq(seq, r, "pauseActivity")) {
3630 //Slog.v(TAG, "userLeaving=" + userLeaving + " handling pause of " + r);
3632 performUserLeavingActivity(r);
3635 r.activity.mConfigChangeFlags |= configChanges;
3636 performPauseActivity(token, finished, r.isPreHoneycomb(), "handlePauseActivity");
3638 // Make sure any pending writes are now committed.
3639 if (r.isPreHoneycomb()) {
3640 QueuedWork.waitToFinish();
3643 // Tell the activity manager we have paused.
3646 ActivityManagerNative.getDefault().activityPaused(token);
3647 } catch (RemoteException ex) {
3648 throw ex.rethrowFromSystemServer();
3651 mSomeActivitiesChanged = true;
3655 final void performUserLeavingActivity(ActivityClientRecord r) {
3656 mInstrumentation.callActivityOnUserLeaving(r.activity);
3659 final Bundle performPauseActivity(IBinder token, boolean finished,
3660 boolean saveState, String reason) {
3661 ActivityClientRecord r = mActivities.get(token);
3662 return r != null ? performPauseActivity(r, finished, saveState, reason) : null;
3665 final Bundle performPauseActivity(ActivityClientRecord r, boolean finished,
3666 boolean saveState, String reason) {
3668 if (r.activity.mFinished) {
3669 // If we are finishing, we won't call onResume() in certain cases.
3670 // So here we likewise don't want to call onPause() if the activity
3674 RuntimeException e = new RuntimeException(
3675 "Performing pause of activity that is not resumed: "
3676 + r.intent.getComponent().toShortString());
3677 Slog.e(TAG, e.getMessage(), e);
3680 r.activity.mFinished = true;
3683 // Next have the activity save its current state and managed dialogs...
3684 if (!r.activity.mFinished && saveState) {
3685 callCallActivityOnSaveInstanceState(r);
3688 performPauseActivityIfNeeded(r, reason);
3690 // Notify any outstanding on paused listeners
3691 ArrayList<OnActivityPausedListener> listeners;
3692 synchronized (mOnPauseListeners) {
3693 listeners = mOnPauseListeners.remove(r.activity);
3695 int size = (listeners != null ? listeners.size() : 0);
3696 for (int i = 0; i < size; i++) {
3697 listeners.get(i).onPaused(r.activity);
3700 return !r.activity.mFinished && saveState ? r.state : null;
3703 private void performPauseActivityIfNeeded(ActivityClientRecord r, String reason) {
3705 // You are already paused silly...
3710 r.activity.mCalled = false;
3711 mInstrumentation.callActivityOnPause(r.activity);
3712 EventLog.writeEvent(LOG_AM_ON_PAUSE_CALLED, UserHandle.myUserId(),
3713 r.activity.getComponentName().getClassName(), reason);
3714 if (!r.activity.mCalled) {
3715 throw new SuperNotCalledException("Activity " + safeToComponentShortString(r.intent)
3716 + " did not call through to super.onPause()");
3718 } catch (SuperNotCalledException e) {
3720 } catch (Exception e) {
3721 if (!mInstrumentation.onException(r.activity, e)) {
3722 throw new RuntimeException("Unable to pause activity "
3723 + safeToComponentShortString(r.intent) + ": " + e.toString(), e);
3729 final void performStopActivity(IBinder token, boolean saveState, String reason) {
3730 ActivityClientRecord r = mActivities.get(token);
3731 performStopActivityInner(r, null, false, saveState, reason);
3734 private static class StopInfo implements Runnable {
3735 ActivityClientRecord activity;
3737 PersistableBundle persistentState;
3738 CharSequence description;
3740 @Override public void run() {
3741 // Tell activity manager we have been stopped.
3743 if (DEBUG_MEMORY_TRIM) Slog.v(TAG, "Reporting activity stopped: " + activity);
3744 ActivityManagerNative.getDefault().activityStopped(
3745 activity.token, state, persistentState, description);
3746 } catch (RemoteException ex) {
3747 if (ex instanceof TransactionTooLargeException
3748 && activity.packageInfo.getTargetSdkVersion() < Build.VERSION_CODES.N) {
3749 Log.e(TAG, "App sent too much data in instance state, so it was ignored", ex);
3752 throw ex.rethrowFromSystemServer();
3757 private static final class ProviderRefCount {
3758 public final IActivityManager.ContentProviderHolder holder;
3759 public final ProviderClientRecord client;
3760 public int stableCount;
3761 public int unstableCount;
3763 // When this is set, the stable and unstable ref counts are 0 and
3764 // we have a pending operation scheduled to remove the ref count
3765 // from the activity manager. On the activity manager we are still
3766 // holding an unstable ref, though it is not reflected in the counts
3768 public boolean removePending;
3770 ProviderRefCount(IActivityManager.ContentProviderHolder inHolder,
3771 ProviderClientRecord inClient, int sCount, int uCount) {
3774 stableCount = sCount;
3775 unstableCount = uCount;
3780 * Core implementation of stopping an activity. Note this is a little
3781 * tricky because the server's meaning of stop is slightly different
3782 * than our client -- for the server, stop means to save state and give
3783 * it the result when it is done, but the window may still be visible.
3784 * For the client, we want to call onStop()/onStart() to indicate when
3785 * the activity's UI visibillity changes.
3787 private void performStopActivityInner(ActivityClientRecord r,
3788 StopInfo info, boolean keepShown, boolean saveState, String reason) {
3789 if (localLOGV) Slog.v(TAG, "Performing stop of " + r);
3791 if (!keepShown && r.stopped) {
3792 if (r.activity.mFinished) {
3793 // If we are finishing, we won't call onResume() in certain
3794 // cases. So here we likewise don't want to call onStop()
3795 // if the activity isn't resumed.
3798 RuntimeException e = new RuntimeException(
3799 "Performing stop of activity that is already stopped: "
3800 + r.intent.getComponent().toShortString());
3801 Slog.e(TAG, e.getMessage(), e);
3802 Slog.e(TAG, r.getStateString());
3805 // One must first be paused before stopped...
3806 performPauseActivityIfNeeded(r, reason);
3810 // First create a thumbnail for the activity...
3811 // For now, don't create the thumbnail here; we are
3812 // doing that by doing a screen snapshot.
3813 info.description = r.activity.onCreateDescription();
3814 } catch (Exception e) {
3815 if (!mInstrumentation.onException(r.activity, e)) {
3816 throw new RuntimeException(
3817 "Unable to save state of activity "
3818 + r.intent.getComponent().toShortString()
3819 + ": " + e.toString(), e);
3824 // Next have the activity save its current state and managed dialogs...
3825 if (!r.activity.mFinished && saveState) {
3826 if (r.state == null) {
3827 callCallActivityOnSaveInstanceState(r);
3834 r.activity.performStop(false /*preserveWindow*/);
3835 } catch (Exception e) {
3836 if (!mInstrumentation.onException(r.activity, e)) {
3837 throw new RuntimeException(
3838 "Unable to stop activity "
3839 + r.intent.getComponent().toShortString()
3840 + ": " + e.toString(), e);
3844 EventLog.writeEvent(LOG_AM_ON_STOP_CALLED, UserHandle.myUserId(),
3845 r.activity.getComponentName().getClassName(), reason);
3850 private void updateVisibility(ActivityClientRecord r, boolean show) {
3851 View v = r.activity.mDecor;
3854 if (!r.activity.mVisibleFromServer) {
3855 r.activity.mVisibleFromServer = true;
3856 mNumVisibleActivities++;
3857 if (r.activity.mVisibleFromClient) {
3858 r.activity.makeVisible();
3861 if (r.newConfig != null) {
3862 performConfigurationChangedForActivity(r, r.newConfig, REPORT_TO_ACTIVITY);
3863 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Updating activity vis "
3864 + r.activityInfo.name + " with new config "
3865 + r.activity.mCurrentConfig);
3869 if (r.activity.mVisibleFromServer) {
3870 r.activity.mVisibleFromServer = false;
3871 mNumVisibleActivities--;
3872 v.setVisibility(View.INVISIBLE);
3878 private void handleStopActivity(IBinder token, boolean show, int configChanges, int seq) {
3879 ActivityClientRecord r = mActivities.get(token);
3880 if (!checkAndUpdateLifecycleSeq(seq, r, "stopActivity")) {
3883 r.activity.mConfigChangeFlags |= configChanges;
3885 StopInfo info = new StopInfo();
3886 performStopActivityInner(r, info, show, true, "handleStopActivity");
3888 if (localLOGV) Slog.v(
3889 TAG, "Finishing stop of " + r + ": show=" + show
3890 + " win=" + r.window);
3892 updateVisibility(r, show);
3894 // Make sure any pending writes are now committed.
3895 if (!r.isPreHoneycomb()) {
3896 QueuedWork.waitToFinish();
3899 // Schedule the call to tell the activity manager we have
3900 // stopped. We don't do this immediately, because we want to
3901 // have a chance for any other pending work (in particular memory
3902 // trim requests) to complete before you tell the activity
3903 // manager to proceed and allow us to go fully into the background.
3905 info.state = r.state;
3906 info.persistentState = r.persistentState;
3908 mSomeActivitiesChanged = true;
3911 private static boolean checkAndUpdateLifecycleSeq(int seq, ActivityClientRecord r,
3916 if (seq < r.lastProcessedSeq) {
3917 if (DEBUG_ORDER) Slog.d(TAG, action + " for " + r + " ignored, because seq=" + seq
3918 + " < mCurrentLifecycleSeq=" + r.lastProcessedSeq);
3921 r.lastProcessedSeq = seq;
3925 final void performRestartActivity(IBinder token) {
3926 ActivityClientRecord r = mActivities.get(token);
3928 r.activity.performRestart();
3933 private void handleWindowVisibility(IBinder token, boolean show) {
3934 ActivityClientRecord r = mActivities.get(token);
3937 Log.w(TAG, "handleWindowVisibility: no activity for token " + token);
3941 if (!show && !r.stopped) {
3942 performStopActivityInner(r, null, show, false, "handleWindowVisibility");
3943 } else if (show && r.stopped) {
3944 // If we are getting ready to gc after going to the background, well
3945 // we are back active so skip it.
3946 unscheduleGcIdler();
3948 r.activity.performRestart();
3951 if (r.activity.mDecor != null) {
3953 TAG, "Handle window " + r + " visibility: " + show);
3954 updateVisibility(r, show);
3956 mSomeActivitiesChanged = true;
3959 private void handleSleeping(IBinder token, boolean sleeping) {
3960 ActivityClientRecord r = mActivities.get(token);
3963 Log.w(TAG, "handleSleeping: no activity for token " + token);
3968 if (!r.stopped && !r.isPreHoneycomb()) {
3971 r.activity.performStop(false /*preserveWindow*/);
3972 } catch (Exception e) {
3973 if (!mInstrumentation.onException(r.activity, e)) {
3974 throw new RuntimeException(
3975 "Unable to stop activity "
3976 + r.intent.getComponent().toShortString()
3977 + ": " + e.toString(), e);
3981 EventLog.writeEvent(LOG_AM_ON_STOP_CALLED, UserHandle.myUserId(),
3982 r.activity.getComponentName().getClassName(), "sleeping");
3985 // Make sure any pending writes are now committed.
3986 if (!r.isPreHoneycomb()) {
3987 QueuedWork.waitToFinish();
3990 // Tell activity manager we slept.
3992 ActivityManagerNative.getDefault().activitySlept(r.token);
3993 } catch (RemoteException ex) {
3994 throw ex.rethrowFromSystemServer();
3997 if (r.stopped && r.activity.mVisibleFromServer) {
3998 r.activity.performRestart();
4004 private void handleSetCoreSettings(Bundle coreSettings) {
4005 synchronized (mResourcesManager) {
4006 mCoreSettings = coreSettings;
4008 onCoreSettingsChange();
4011 private void onCoreSettingsChange() {
4012 boolean debugViewAttributes =
4013 mCoreSettings.getInt(Settings.Global.DEBUG_VIEW_ATTRIBUTES, 0) != 0;
4014 if (debugViewAttributes != View.mDebugViewAttributes) {
4015 View.mDebugViewAttributes = debugViewAttributes;
4017 // request all activities to relaunch for the changes to take place
4018 for (Map.Entry<IBinder, ActivityClientRecord> entry : mActivities.entrySet()) {
4019 requestRelaunchActivity(entry.getKey(), null, null, 0, false, null, null, false,
4020 false /* preserveWindow */);
4025 private void handleUpdatePackageCompatibilityInfo(UpdateCompatibilityData data) {
4026 LoadedApk apk = peekPackageInfo(data.pkg, false);
4028 apk.setCompatibilityInfo(data.info);
4030 apk = peekPackageInfo(data.pkg, true);
4032 apk.setCompatibilityInfo(data.info);
4034 handleConfigurationChanged(mConfiguration, data.info);
4035 WindowManagerGlobal.getInstance().reportNewConfiguration(mConfiguration);
4038 private void deliverResults(ActivityClientRecord r, List<ResultInfo> results) {
4039 final int N = results.size();
4040 for (int i=0; i<N; i++) {
4041 ResultInfo ri = results.get(i);
4043 if (ri.mData != null) {
4044 ri.mData.setExtrasClassLoader(r.activity.getClassLoader());
4045 ri.mData.prepareToEnterProcess();
4047 if (DEBUG_RESULTS) Slog.v(TAG,
4048 "Delivering result to activity " + r + " : " + ri);
4049 r.activity.dispatchActivityResult(ri.mResultWho,
4050 ri.mRequestCode, ri.mResultCode, ri.mData);
4051 } catch (Exception e) {
4052 if (!mInstrumentation.onException(r.activity, e)) {
4053 throw new RuntimeException(
4054 "Failure delivering result " + ri + " to activity "
4055 + r.intent.getComponent().toShortString()
4056 + ": " + e.toString(), e);
4062 private void handleSendResult(ResultData res) {
4063 ActivityClientRecord r = mActivities.get(res.token);
4064 if (DEBUG_RESULTS) Slog.v(TAG, "Handling send result to " + r);
4066 final boolean resumed = !r.paused;
4067 if (!r.activity.mFinished && r.activity.mDecor != null
4068 && r.hideForNow && resumed) {
4069 // We had hidden the activity because it started another
4070 // one... we have gotten a result back and we are not
4071 // paused, so make sure our window is visible.
4072 updateVisibility(r, true);
4077 r.activity.mCalled = false;
4078 r.activity.mTemporaryPause = true;
4079 mInstrumentation.callActivityOnPause(r.activity);
4080 if (!r.activity.mCalled) {
4081 throw new SuperNotCalledException(
4082 "Activity " + r.intent.getComponent().toShortString()
4083 + " did not call through to super.onPause()");
4085 } catch (SuperNotCalledException e) {
4087 } catch (Exception e) {
4088 if (!mInstrumentation.onException(r.activity, e)) {
4089 throw new RuntimeException(
4090 "Unable to pause activity "
4091 + r.intent.getComponent().toShortString()
4092 + ": " + e.toString(), e);
4096 deliverResults(r, res.results);
4098 r.activity.performResume();
4099 r.activity.mTemporaryPause = false;
4104 public final ActivityClientRecord performDestroyActivity(IBinder token, boolean finishing) {
4105 return performDestroyActivity(token, finishing, 0, false);
4108 private ActivityClientRecord performDestroyActivity(IBinder token, boolean finishing,
4109 int configChanges, boolean getNonConfigInstance) {
4110 ActivityClientRecord r = mActivities.get(token);
4111 Class<? extends Activity> activityClass = null;
4112 if (localLOGV) Slog.v(TAG, "Performing finish of " + r);
4114 activityClass = r.activity.getClass();
4115 r.activity.mConfigChangeFlags |= configChanges;
4117 r.activity.mFinished = true;
4120 performPauseActivityIfNeeded(r, "destroy");
4124 r.activity.performStop(r.mPreserveWindow);
4125 } catch (SuperNotCalledException e) {
4127 } catch (Exception e) {
4128 if (!mInstrumentation.onException(r.activity, e)) {
4129 throw new RuntimeException(
4130 "Unable to stop activity "
4131 + safeToComponentShortString(r.intent)
4132 + ": " + e.toString(), e);
4136 EventLog.writeEvent(LOG_AM_ON_STOP_CALLED, UserHandle.myUserId(),
4137 r.activity.getComponentName().getClassName(), "destroy");
4139 if (getNonConfigInstance) {
4141 r.lastNonConfigurationInstances
4142 = r.activity.retainNonConfigurationInstances();
4143 } catch (Exception e) {
4144 if (!mInstrumentation.onException(r.activity, e)) {
4145 throw new RuntimeException(
4146 "Unable to retain activity "
4147 + r.intent.getComponent().toShortString()
4148 + ": " + e.toString(), e);
4153 r.activity.mCalled = false;
4154 mInstrumentation.callActivityOnDestroy(r.activity);
4155 if (!r.activity.mCalled) {
4156 throw new SuperNotCalledException(
4157 "Activity " + safeToComponentShortString(r.intent) +
4158 " did not call through to super.onDestroy()");
4160 if (r.window != null) {
4161 r.window.closeAllPanels();
4163 } catch (SuperNotCalledException e) {
4165 } catch (Exception e) {
4166 if (!mInstrumentation.onException(r.activity, e)) {
4167 throw new RuntimeException(
4168 "Unable to destroy activity " + safeToComponentShortString(r.intent)
4169 + ": " + e.toString(), e);
4173 mActivities.remove(token);
4174 StrictMode.decrementExpectedActivityCount(activityClass);
4178 private static String safeToComponentShortString(Intent intent) {
4179 ComponentName component = intent.getComponent();
4180 return component == null ? "[Unknown]" : component.toShortString();
4183 private void handleDestroyActivity(IBinder token, boolean finishing,
4184 int configChanges, boolean getNonConfigInstance) {
4185 ActivityClientRecord r = performDestroyActivity(token, finishing,
4186 configChanges, getNonConfigInstance);
4188 cleanUpPendingRemoveWindows(r, finishing);
4189 WindowManager wm = r.activity.getWindowManager();
4190 View v = r.activity.mDecor;
4192 if (r.activity.mVisibleFromServer) {
4193 mNumVisibleActivities--;
4195 IBinder wtoken = v.getWindowToken();
4196 if (r.activity.mWindowAdded) {
4197 if (r.mPreserveWindow) {
4198 // Hold off on removing this until the new activity's
4199 // window is being added.
4200 r.mPendingRemoveWindow = r.window;
4201 r.mPendingRemoveWindowManager = wm;
4202 // We can only keep the part of the view hierarchy that we control,
4203 // everything else must be removed, because it might not be able to
4204 // behave properly when activity is relaunching.
4205 r.window.clearContentView();
4207 wm.removeViewImmediate(v);
4210 if (wtoken != null && r.mPendingRemoveWindow == null) {
4211 WindowManagerGlobal.getInstance().closeAll(wtoken,
4212 r.activity.getClass().getName(), "Activity");
4213 } else if (r.mPendingRemoveWindow != null) {
4214 // We're preserving only one window, others should be closed so app views
4215 // will be detached before the final tear down. It should be done now because
4216 // some components (e.g. WebView) rely on detach callbacks to perform receiver
4217 // unregister and other cleanup.
4218 WindowManagerGlobal.getInstance().closeAllExceptView(token, v,
4219 r.activity.getClass().getName(), "Activity");
4221 r.activity.mDecor = null;
4223 if (r.mPendingRemoveWindow == null) {
4224 // If we are delaying the removal of the activity window, then
4225 // we can't clean up all windows here. Note that we can't do
4226 // so later either, which means any windows that aren't closed
4227 // by the app will leak. Well we try to warning them a lot
4228 // about leaking windows, because that is a bug, so if they are
4229 // using this recreate facility then they get to live with leaks.
4230 WindowManagerGlobal.getInstance().closeAll(token,
4231 r.activity.getClass().getName(), "Activity");
4234 // Mocked out contexts won't be participating in the normal
4235 // process lifecycle, but if we're running with a proper
4236 // ApplicationContext we need to have it tear down things
4238 Context c = r.activity.getBaseContext();
4239 if (c instanceof ContextImpl) {
4240 ((ContextImpl) c).scheduleFinalCleanup(
4241 r.activity.getClass().getName(), "Activity");
4246 ActivityManagerNative.getDefault().activityDestroyed(token);
4247 } catch (RemoteException ex) {
4248 throw ex.rethrowFromSystemServer();
4251 mSomeActivitiesChanged = true;
4255 * @param preserveWindow Whether the activity should try to reuse the window it created,
4256 * including the decor view after the relaunch.
4258 public final void requestRelaunchActivity(IBinder token,
4259 List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents,
4260 int configChanges, boolean notResumed, Configuration config,
4261 Configuration overrideConfig, boolean fromServer, boolean preserveWindow) {
4262 ActivityClientRecord target = null;
4264 synchronized (mResourcesManager) {
4265 for (int i=0; i<mRelaunchingActivities.size(); i++) {
4266 ActivityClientRecord r = mRelaunchingActivities.get(i);
4267 if (DEBUG_ORDER) Slog.d(TAG, "requestRelaunchActivity: " + this + ", trying: " + r);
4268 if (r.token == token) {
4270 if (pendingResults != null) {
4271 if (r.pendingResults != null) {
4272 r.pendingResults.addAll(pendingResults);
4274 r.pendingResults = pendingResults;
4277 if (pendingNewIntents != null) {
4278 if (r.pendingIntents != null) {
4279 r.pendingIntents.addAll(pendingNewIntents);
4281 r.pendingIntents = pendingNewIntents;
4285 // For each relaunch request, activity manager expects an answer
4286 if (!r.onlyLocalRequest && fromServer) {
4288 ActivityManagerNative.getDefault().activityRelaunched(token);
4289 } catch (RemoteException e) {
4290 throw e.rethrowFromSystemServer();
4297 if (target == null) {
4298 if (DEBUG_ORDER) Slog.d(TAG, "requestRelaunchActivity: target is null, fromServer:"
4300 target = new ActivityClientRecord();
4301 target.token = token;
4302 target.pendingResults = pendingResults;
4303 target.pendingIntents = pendingNewIntents;
4304 target.mPreserveWindow = preserveWindow;
4306 final ActivityClientRecord existing = mActivities.get(token);
4307 if (DEBUG_ORDER) Slog.d(TAG, "requestRelaunchActivity: " + existing);
4308 if (existing != null) {
4309 if (DEBUG_ORDER) Slog.d(TAG, "requestRelaunchActivity: paused= "
4310 + existing.paused);;
4311 target.startsNotResumed = existing.paused;
4312 target.overrideConfig = existing.overrideConfig;
4314 target.onlyLocalRequest = true;
4316 mRelaunchingActivities.add(target);
4317 sendMessage(H.RELAUNCH_ACTIVITY, target);
4321 target.startsNotResumed = notResumed;
4322 target.onlyLocalRequest = false;
4324 if (config != null) {
4325 target.createdConfig = config;
4327 if (overrideConfig != null) {
4328 target.overrideConfig = overrideConfig;
4330 target.pendingConfigChanges |= configChanges;
4331 target.relaunchSeq = getLifecycleSeq();
4333 if (DEBUG_ORDER) Slog.d(TAG, "relaunchActivity " + ActivityThread.this + ", target "
4334 + target + " operation received seq: " + target.relaunchSeq);
4337 private void handleRelaunchActivity(ActivityClientRecord tmp) {
4338 // If we are getting ready to gc after going to the background, well
4339 // we are back active so skip it.
4340 unscheduleGcIdler();
4341 mSomeActivitiesChanged = true;
4343 Configuration changedConfig = null;
4344 int configChanges = 0;
4346 // First: make sure we have the most recent configuration and most
4347 // recent version of the activity, or skip it if some previous call
4348 // had taken a more recent version.
4349 synchronized (mResourcesManager) {
4350 int N = mRelaunchingActivities.size();
4351 IBinder token = tmp.token;
4353 for (int i=0; i<N; i++) {
4354 ActivityClientRecord r = mRelaunchingActivities.get(i);
4355 if (r.token == token) {
4357 configChanges |= tmp.pendingConfigChanges;
4358 mRelaunchingActivities.remove(i);
4365 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Abort, activity not relaunching!");
4369 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Relaunching activity "
4370 + tmp.token + " with configChanges=0x"
4371 + Integer.toHexString(configChanges));
4373 if (mPendingConfiguration != null) {
4374 changedConfig = mPendingConfiguration;
4375 mPendingConfiguration = null;
4379 if (tmp.lastProcessedSeq > tmp.relaunchSeq) {
4380 Slog.wtf(TAG, "For some reason target: " + tmp + " has lower sequence: "
4381 + tmp.relaunchSeq + " than current sequence: " + tmp.lastProcessedSeq);
4383 tmp.lastProcessedSeq = tmp.relaunchSeq;
4385 if (tmp.createdConfig != null) {
4386 // If the activity manager is passing us its current config,
4387 // assume that is really what we want regardless of what we
4388 // may have pending.
4389 if (mConfiguration == null
4390 || (tmp.createdConfig.isOtherSeqNewer(mConfiguration)
4391 && mConfiguration.diff(tmp.createdConfig) != 0)) {
4392 if (changedConfig == null
4393 || tmp.createdConfig.isOtherSeqNewer(changedConfig)) {
4394 changedConfig = tmp.createdConfig;
4399 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Relaunching activity "
4400 + tmp.token + ": changedConfig=" + changedConfig);
4402 // If there was a pending configuration change, execute it first.
4403 if (changedConfig != null) {
4404 mCurDefaultDisplayDpi = changedConfig.densityDpi;
4405 updateDefaultDensity();
4406 handleConfigurationChanged(changedConfig, null);
4409 ActivityClientRecord r = mActivities.get(tmp.token);
4410 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handling relaunch of " + r);
4412 if (!tmp.onlyLocalRequest) {
4414 ActivityManagerNative.getDefault().activityRelaunched(tmp.token);
4415 } catch (RemoteException e) {
4416 throw e.rethrowFromSystemServer();
4422 r.activity.mConfigChangeFlags |= configChanges;
4423 r.onlyLocalRequest = tmp.onlyLocalRequest;
4424 r.mPreserveWindow = tmp.mPreserveWindow;
4425 r.lastProcessedSeq = tmp.lastProcessedSeq;
4426 r.relaunchSeq = tmp.relaunchSeq;
4427 Intent currentIntent = r.activity.mIntent;
4429 r.activity.mChangingConfigurations = true;
4431 // If we are preserving the main window across relaunches we would also like to preserve
4432 // the children. However the client side view system does not support preserving
4433 // the child views so we notify the window manager to expect these windows to
4434 // be replaced and defer requests to destroy or hide them. This way we can achieve
4435 // visual continuity. It's important that we do this here prior to pause and destroy
4436 // as that is when we may hide or remove the child views.
4438 // There is another scenario, if we have decided locally to relaunch the app from a
4439 // call to recreate, then none of the windows will be prepared for replacement or
4440 // preserved by the server, so we want to notify it that we are preparing to replace
4443 if (r.mPreserveWindow || r.onlyLocalRequest) {
4444 WindowManagerGlobal.getWindowSession().prepareToReplaceWindows(
4445 r.token, !r.onlyLocalRequest);
4447 } catch (RemoteException e) {
4448 throw e.rethrowFromSystemServer();
4451 // Need to ensure state is saved.
4453 performPauseActivity(r.token, false, r.isPreHoneycomb(), "handleRelaunchActivity");
4455 if (r.state == null && !r.stopped && !r.isPreHoneycomb()) {
4456 callCallActivityOnSaveInstanceState(r);
4459 handleDestroyActivity(r.token, false, configChanges, true);
4463 r.hideForNow = false;
4465 // Merge any pending results and pending intents; don't just replace them
4466 if (tmp.pendingResults != null) {
4467 if (r.pendingResults == null) {
4468 r.pendingResults = tmp.pendingResults;
4470 r.pendingResults.addAll(tmp.pendingResults);
4473 if (tmp.pendingIntents != null) {
4474 if (r.pendingIntents == null) {
4475 r.pendingIntents = tmp.pendingIntents;
4477 r.pendingIntents.addAll(tmp.pendingIntents);
4480 r.startsNotResumed = tmp.startsNotResumed;
4481 r.overrideConfig = tmp.overrideConfig;
4483 handleLaunchActivity(r, currentIntent, "handleRelaunchActivity");
4485 if (!tmp.onlyLocalRequest) {
4487 ActivityManagerNative.getDefault().activityRelaunched(r.token);
4488 if (r.window != null) {
4489 r.window.reportActivityRelaunched();
4491 } catch (RemoteException e) {
4492 throw e.rethrowFromSystemServer();
4497 private void callCallActivityOnSaveInstanceState(ActivityClientRecord r) {
4498 r.state = new Bundle();
4499 r.state.setAllowFds(false);
4500 if (r.isPersistable()) {
4501 r.persistentState = new PersistableBundle();
4502 mInstrumentation.callActivityOnSaveInstanceState(r.activity, r.state,
4505 mInstrumentation.callActivityOnSaveInstanceState(r.activity, r.state);
4509 ArrayList<ComponentCallbacks2> collectComponentCallbacks(
4510 boolean allActivities, Configuration newConfig) {
4511 ArrayList<ComponentCallbacks2> callbacks
4512 = new ArrayList<ComponentCallbacks2>();
4514 synchronized (mResourcesManager) {
4515 final int NAPP = mAllApplications.size();
4516 for (int i=0; i<NAPP; i++) {
4517 callbacks.add(mAllApplications.get(i));
4519 final int NACT = mActivities.size();
4520 for (int i=0; i<NACT; i++) {
4521 ActivityClientRecord ar = mActivities.valueAt(i);
4522 Activity a = ar.activity;
4524 Configuration thisConfig = applyConfigCompatMainThread(
4525 mCurDefaultDisplayDpi, newConfig,
4526 ar.packageInfo.getCompatibilityInfo());
4527 if (!ar.activity.mFinished && (allActivities || !ar.paused)) {
4528 // If the activity is currently resumed, its configuration
4529 // needs to change right now.
4531 } else if (thisConfig != null) {
4532 // Otherwise, we will tell it about the change
4533 // the next time it is resumed or shown. Note that
4534 // the activity manager may, before then, decide the
4535 // activity needs to be destroyed to handle its new
4537 if (DEBUG_CONFIGURATION) {
4538 Slog.v(TAG, "Setting activity "
4539 + ar.activityInfo.name + " newConfig=" + thisConfig);
4541 ar.newConfig = thisConfig;
4545 final int NSVC = mServices.size();
4546 for (int i=0; i<NSVC; i++) {
4547 callbacks.add(mServices.valueAt(i));
4550 synchronized (mProviderMap) {
4551 final int NPRV = mLocalProviders.size();
4552 for (int i=0; i<NPRV; i++) {
4553 callbacks.add(mLocalProviders.valueAt(i).mLocalProvider);
4561 * Updates the configuration for an Activity. The ActivityClientRecord's
4562 * {@link ActivityClientRecord#overrideConfig} is used to compute the final Configuration for
4563 * that Activity. {@link ActivityClientRecord#tmpConfig} is used as a temporary for delivering
4564 * the updated Configuration.
4565 * @param r ActivityClientRecord representing the Activity.
4566 * @param newBaseConfig The new configuration to use. This may be augmented with
4567 * {@link ActivityClientRecord#overrideConfig}.
4568 * @param reportToActivity true if the change should be reported to the Activity's callback.
4570 private void performConfigurationChangedForActivity(ActivityClientRecord r,
4571 Configuration newBaseConfig,
4572 boolean reportToActivity) {
4573 r.tmpConfig.setTo(newBaseConfig);
4574 if (r.overrideConfig != null) {
4575 r.tmpConfig.updateFrom(r.overrideConfig);
4577 performConfigurationChanged(r.activity, r.token, r.tmpConfig, r.overrideConfig,
4579 freeTextLayoutCachesIfNeeded(r.activity.mCurrentConfig.diff(r.tmpConfig));
4583 * Creates a new Configuration only if override would modify base. Otherwise returns base.
4584 * @param base The base configuration.
4585 * @param override The update to apply to the base configuration. Can be null.
4586 * @return A Configuration representing base with override applied.
4588 private static Configuration createNewConfigAndUpdateIfNotNull(@NonNull Configuration base,
4589 @Nullable Configuration override) {
4590 if (override == null) {
4593 Configuration newConfig = new Configuration(base);
4594 newConfig.updateFrom(override);
4599 * Decides whether to update an Activity's configuration and whether to tell the
4600 * Activity/Component about it.
4601 * @param cb The component callback to notify of configuration change.
4602 * @param activityToken The Activity binder token for which this configuration change happened.
4603 * If the change is global, this is null.
4604 * @param newConfig The new configuration.
4605 * @param amOverrideConfig The override config that differentiates the Activity's configuration
4606 * from the base global configuration.
4607 * This is supplied by ActivityManager.
4608 * @param reportToActivity Notify the Activity of the change.
4610 private void performConfigurationChanged(ComponentCallbacks2 cb,
4611 IBinder activityToken,
4612 Configuration newConfig,
4613 Configuration amOverrideConfig,
4614 boolean reportToActivity) {
4615 // Only for Activity objects, check that they actually call up to their
4616 // superclass implementation. ComponentCallbacks2 is an interface, so
4617 // we check the runtime type and act accordingly.
4618 Activity activity = (cb instanceof Activity) ? (Activity) cb : null;
4619 if (activity != null) {
4620 activity.mCalled = false;
4623 boolean shouldChangeConfig = false;
4624 if ((activity == null) || (activity.mCurrentConfig == null)) {
4625 shouldChangeConfig = true;
4627 // If the new config is the same as the config this Activity
4628 // is already running with then don't bother calling
4629 // onConfigurationChanged
4630 int diff = activity.mCurrentConfig.diff(newConfig);
4632 shouldChangeConfig = true;
4636 if (shouldChangeConfig) {
4637 // Propagate the configuration change to the Activity and ResourcesManager.
4639 // ContextThemeWrappers may override the configuration for that context.
4640 // We must check and apply any overrides defined.
4641 Configuration contextThemeWrapperOverrideConfig = null;
4642 if (cb instanceof ContextThemeWrapper) {
4643 final ContextThemeWrapper contextThemeWrapper = (ContextThemeWrapper) cb;
4644 contextThemeWrapperOverrideConfig = contextThemeWrapper.getOverrideConfiguration();
4647 // We only update an Activity's configuration if this is not a global
4648 // configuration change. This must also be done before the callback,
4649 // or else we violate the contract that the new resources are available
4650 // in {@link ComponentCallbacks2#onConfigurationChanged(Configuration)}.
4651 if (activityToken != null) {
4652 // Apply the ContextThemeWrapper override if necessary.
4653 // NOTE: Make sure the configurations are not modified, as they are treated
4654 // as immutable in many places.
4655 final Configuration finalOverrideConfig = createNewConfigAndUpdateIfNotNull(
4656 amOverrideConfig, contextThemeWrapperOverrideConfig);
4657 mResourcesManager.updateResourcesForActivity(activityToken, finalOverrideConfig);
4660 if (reportToActivity) {
4661 // Apply the ContextThemeWrapper override if necessary.
4662 // NOTE: Make sure the configurations are not modified, as they are treated
4663 // as immutable in many places.
4664 final Configuration configToReport = createNewConfigAndUpdateIfNotNull(
4665 newConfig, contextThemeWrapperOverrideConfig);
4666 cb.onConfigurationChanged(configToReport);
4669 if (activity != null) {
4670 if (reportToActivity && !activity.mCalled) {
4671 throw new SuperNotCalledException(
4672 "Activity " + activity.getLocalClassName() +
4673 " did not call through to super.onConfigurationChanged()");
4675 activity.mConfigChangeFlags = 0;
4676 activity.mCurrentConfig = new Configuration(newConfig);
4681 public final void applyConfigurationToResources(Configuration config) {
4682 synchronized (mResourcesManager) {
4683 mResourcesManager.applyConfigurationToResourcesLocked(config, null);
4687 final Configuration applyCompatConfiguration(int displayDensity) {
4688 Configuration config = mConfiguration;
4689 if (mCompatConfiguration == null) {
4690 mCompatConfiguration = new Configuration();
4692 mCompatConfiguration.setTo(mConfiguration);
4693 if (mResourcesManager.applyCompatConfigurationLocked(displayDensity,
4694 mCompatConfiguration)) {
4695 config = mCompatConfiguration;
4700 final void handleConfigurationChanged(Configuration config, CompatibilityInfo compat) {
4704 synchronized (mResourcesManager) {
4705 if (mPendingConfiguration != null) {
4706 if (!mPendingConfiguration.isOtherSeqNewer(config)) {
4707 config = mPendingConfiguration;
4708 mCurDefaultDisplayDpi = config.densityDpi;
4709 updateDefaultDensity();
4711 mPendingConfiguration = null;
4714 if (config == null) {
4718 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handle configuration changed: "
4721 mResourcesManager.applyConfigurationToResourcesLocked(config, compat);
4722 updateLocaleListFromAppContext(mInitialApplication.getApplicationContext(),
4723 mResourcesManager.getConfiguration().getLocales());
4725 if (mConfiguration == null) {
4726 mConfiguration = new Configuration();
4728 if (!mConfiguration.isOtherSeqNewer(config) && compat == null) {
4732 configDiff = mConfiguration.updateFrom(config);
4733 config = applyCompatConfiguration(mCurDefaultDisplayDpi);
4735 final Theme systemTheme = getSystemContext().getTheme();
4736 if ((systemTheme.getChangingConfigurations() & configDiff) != 0) {
4737 systemTheme.rebase();
4741 ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(false, config);
4743 freeTextLayoutCachesIfNeeded(configDiff);
4745 if (callbacks != null) {
4746 final int N = callbacks.size();
4747 for (int i=0; i<N; i++) {
4748 ComponentCallbacks2 cb = callbacks.get(i);
4749 if (cb instanceof Activity) {
4750 // If callback is an Activity - call corresponding method to consider override
4751 // config and avoid onConfigurationChanged if it hasn't changed.
4752 Activity a = (Activity) cb;
4753 performConfigurationChangedForActivity(mActivities.get(a.getActivityToken()),
4754 config, REPORT_TO_ACTIVITY);
4756 performConfigurationChanged(cb, null, config, null, REPORT_TO_ACTIVITY);
4762 static void freeTextLayoutCachesIfNeeded(int configDiff) {
4763 if (configDiff != 0) {
4764 // Ask text layout engine to free its caches if there is a locale change
4765 boolean hasLocaleConfigChange = ((configDiff & ActivityInfo.CONFIG_LOCALE) != 0);
4766 if (hasLocaleConfigChange) {
4767 Canvas.freeTextLayoutCaches();
4768 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Cleared TextLayout Caches");
4773 final void handleActivityConfigurationChanged(ActivityConfigChangeData data,
4774 boolean reportToActivity) {
4775 ActivityClientRecord r = mActivities.get(data.activityToken);
4776 if (r == null || r.activity == null) {
4780 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handle activity config changed: "
4781 + r.activityInfo.name + ", with callback=" + reportToActivity);
4783 r.overrideConfig = data.overrideConfig;
4784 performConfigurationChangedForActivity(r, mCompatConfiguration, reportToActivity);
4785 mSomeActivitiesChanged = true;
4788 final void handleProfilerControl(boolean start, ProfilerInfo profilerInfo, int profileType) {
4791 switch (profileType) {
4793 mProfiler.setProfiler(profilerInfo);
4794 mProfiler.startProfiling();
4797 } catch (RuntimeException e) {
4798 Slog.w(TAG, "Profiling failed on path " + profilerInfo.profileFile
4799 + " -- can the process access this path?");
4802 profilerInfo.profileFd.close();
4803 } catch (IOException e) {
4804 Slog.w(TAG, "Failure closing profile fd", e);
4808 switch (profileType) {
4810 mProfiler.stopProfiling();
4817 * Public entrypoint to stop profiling. This is required to end profiling when the app crashes,
4818 * so that profiler data won't be lost.
4822 public void stopProfiling() {
4823 mProfiler.stopProfiling();
4826 static final void handleDumpHeap(boolean managed, DumpHeapData dhd) {
4829 Debug.dumpHprofData(dhd.path, dhd.fd.getFileDescriptor());
4830 } catch (IOException e) {
4831 Slog.w(TAG, "Managed heap dump failed on path " + dhd.path
4832 + " -- can the process access this path?");
4836 } catch (IOException e) {
4837 Slog.w(TAG, "Failure closing profile fd", e);
4841 Debug.dumpNativeHeap(dhd.fd.getFileDescriptor());
4844 ActivityManagerNative.getDefault().dumpHeapFinished(dhd.path);
4845 } catch (RemoteException e) {
4846 throw e.rethrowFromSystemServer();
4850 final void handleDispatchPackageBroadcast(int cmd, String[] packages) {
4851 boolean hasPkgInfo = false;
4853 case IApplicationThread.PACKAGE_REMOVED:
4854 case IApplicationThread.PACKAGE_REMOVED_DONT_KILL:
4856 final boolean killApp = cmd == IApplicationThread.PACKAGE_REMOVED;
4857 if (packages == null) {
4860 synchronized (mResourcesManager) {
4861 for (int i = packages.length - 1; i >= 0; i--) {
4863 WeakReference<LoadedApk> ref = mPackages.get(packages[i]);
4864 if (ref != null && ref.get() != null) {
4867 ref = mResourcePackages.get(packages[i]);
4868 if (ref != null && ref.get() != null) {
4874 mPackages.remove(packages[i]);
4875 mResourcePackages.remove(packages[i]);
4881 case IApplicationThread.PACKAGE_REPLACED:
4883 if (packages == null) {
4886 synchronized (mResourcesManager) {
4887 for (int i = packages.length - 1; i >= 0; i--) {
4888 WeakReference<LoadedApk> ref = mPackages.get(packages[i]);
4889 LoadedApk pkgInfo = ref != null ? ref.get() : null;
4890 if (pkgInfo != null) {
4893 ref = mResourcePackages.get(packages[i]);
4894 pkgInfo = ref != null ? ref.get() : null;
4895 if (pkgInfo != null) {
4899 // If the package is being replaced, yet it still has a valid
4900 // LoadedApk object, the package was updated with _DONT_KILL.
4901 // Adjust it's internal references to the application info and
4903 if (pkgInfo != null) {
4905 final String packageName = packages[i];
4906 final ApplicationInfo aInfo =
4907 sPackageManager.getApplicationInfo(
4910 UserHandle.myUserId());
4912 if (mActivities.size() > 0) {
4913 for (ActivityClientRecord ar : mActivities.values()) {
4914 if (ar.activityInfo.applicationInfo.packageName
4915 .equals(packageName)) {
4916 ar.activityInfo.applicationInfo = aInfo;
4917 ar.packageInfo = pkgInfo;
4921 final List<String> oldPaths =
4922 sPackageManager.getPreviousCodePaths(packageName);
4923 pkgInfo.updateApplicationInfo(aInfo, oldPaths);
4924 } catch (RemoteException e) {
4932 ApplicationPackageManager.handlePackageBroadcast(cmd, packages, hasPkgInfo);
4935 final void handleLowMemory() {
4936 ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(true, null);
4938 final int N = callbacks.size();
4939 for (int i=0; i<N; i++) {
4940 callbacks.get(i).onLowMemory();
4943 // Ask SQLite to free up as much memory as it can, mostly from its page caches.
4944 if (Process.myUid() != Process.SYSTEM_UID) {
4945 int sqliteReleased = SQLiteDatabase.releaseMemory();
4946 EventLog.writeEvent(SQLITE_MEM_RELEASED_EVENT_LOG_TAG, sqliteReleased);
4949 // Ask graphics to free up as much as possible (font/image caches)
4950 Canvas.freeCaches();
4952 // Ask text layout engine to free also as much as possible
4953 Canvas.freeTextLayoutCaches();
4955 BinderInternal.forceGc("mem");
4958 final void handleTrimMemory(int level) {
4959 if (DEBUG_MEMORY_TRIM) Slog.v(TAG, "Trimming memory to level: " + level);
4961 ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(true, null);
4963 final int N = callbacks.size();
4964 for (int i = 0; i < N; i++) {
4965 callbacks.get(i).onTrimMemory(level);
4968 WindowManagerGlobal.getInstance().trimMemory(level);
4971 private void setupGraphicsSupport(LoadedApk info, File cacheDir) {
4972 if (Process.isIsolated()) {
4973 // Isolated processes aren't going to do UI.
4976 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "setupGraphicsSupport");
4978 int uid = Process.myUid();
4979 String[] packages = getPackageManager().getPackagesForUid(uid);
4981 // If there are several packages in this application we won't
4982 // initialize the graphics disk caches
4983 if (packages != null && packages.length == 1) {
4984 ThreadedRenderer.setupDiskCache(cacheDir);
4985 RenderScriptCacheDir.setupDiskCache(cacheDir);
4987 } catch (RemoteException e) {
4988 throw e.rethrowFromSystemServer();
4990 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
4994 private void updateDefaultDensity() {
4995 final int densityDpi = mCurDefaultDisplayDpi;
4996 if (!mDensityCompatMode
4997 && densityDpi != Configuration.DENSITY_DPI_UNDEFINED
4998 && densityDpi != DisplayMetrics.DENSITY_DEVICE) {
4999 DisplayMetrics.DENSITY_DEVICE = densityDpi;
5000 Bitmap.setDefaultDensity(densityDpi);
5005 * Returns the correct library directory for the current ABI.
5007 * If we're dealing with a multi-arch application that has both 32 and 64 bit shared
5008 * libraries, we might need to choose the secondary depending on what the current
5009 * runtime's instruction set is.
5011 private String getInstrumentationLibrary(ApplicationInfo appInfo, InstrumentationInfo insInfo) {
5012 if (appInfo.primaryCpuAbi != null && appInfo.secondaryCpuAbi != null) {
5013 // Get the instruction set supported by the secondary ABI. In the presence
5014 // of a native bridge this might be different than the one secondary ABI used.
5015 String secondaryIsa =
5016 VMRuntime.getInstructionSet(appInfo.secondaryCpuAbi);
5017 final String secondaryDexCodeIsa =
5018 SystemProperties.get("ro.dalvik.vm.isa." + secondaryIsa);
5019 secondaryIsa = secondaryDexCodeIsa.isEmpty() ? secondaryIsa : secondaryDexCodeIsa;
5021 final String runtimeIsa = VMRuntime.getRuntime().vmInstructionSet();
5022 if (runtimeIsa.equals(secondaryIsa)) {
5023 return insInfo.secondaryNativeLibraryDir;
5026 return insInfo.nativeLibraryDir;
5030 * The LocaleList set for the app's resources may have been shuffled so that the preferred
5031 * Locale is at position 0. We must find the index of this preferred Locale in the
5032 * original LocaleList.
5034 private void updateLocaleListFromAppContext(Context context, LocaleList newLocaleList) {
5035 final Locale bestLocale = context.getResources().getConfiguration().getLocales().get(0);
5036 final int newLocaleListSize = newLocaleList.size();
5037 for (int i = 0; i < newLocaleListSize; i++) {
5038 if (bestLocale.equals(newLocaleList.get(i))) {
5039 LocaleList.setDefault(newLocaleList, i);
5044 // The app may have overridden the LocaleList with its own Locale
5045 // (not present in the available list). Push the chosen Locale
5046 // to the front of the list.
5047 LocaleList.setDefault(new LocaleList(bestLocale, newLocaleList));
5050 private void handleBindApplication(AppBindData data) {
5051 // Register the UI Thread as a sensitive thread to the runtime.
5052 VMRuntime.registerSensitiveThread();
5053 if (data.trackAllocation) {
5054 DdmVmInternal.enableRecentAllocations(true);
5057 // Note when this process has started.
5058 Process.setStartTimes(SystemClock.elapsedRealtime(), SystemClock.uptimeMillis());
5060 mBoundApplication = data;
5061 mConfiguration = new Configuration(data.config);
5062 mCompatConfiguration = new Configuration(data.config);
5064 mProfiler = new Profiler();
5065 if (data.initProfilerInfo != null) {
5066 mProfiler.profileFile = data.initProfilerInfo.profileFile;
5067 mProfiler.profileFd = data.initProfilerInfo.profileFd;
5068 mProfiler.samplingInterval = data.initProfilerInfo.samplingInterval;
5069 mProfiler.autoStopProfiler = data.initProfilerInfo.autoStopProfiler;
5072 // send up app name; do this *before* waiting for debugger
5073 Process.setArgV0(data.processName);
5074 android.ddm.DdmHandleAppName.setAppName(data.processName,
5075 UserHandle.myUserId());
5077 if (data.persistent) {
5078 // Persistent processes on low-memory devices do not get to
5079 // use hardware accelerated drawing, since this can add too much
5080 // overhead to the process.
5081 if (!ActivityManager.isHighEndGfx()) {
5082 ThreadedRenderer.disable(false);
5086 if (mProfiler.profileFd != null) {
5087 mProfiler.startProfiling();
5090 // If the app is Honeycomb MR1 or earlier, switch its AsyncTask
5091 // implementation to use the pool executor. Normally, we use the
5092 // serialized executor as the default. This has to happen in the
5093 // main thread so the main looper is set right.
5094 if (data.appInfo.targetSdkVersion <= android.os.Build.VERSION_CODES.HONEYCOMB_MR1) {
5095 AsyncTask.setDefaultExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
5098 Message.updateCheckRecycle(data.appInfo.targetSdkVersion);
5101 * Before spawning a new process, reset the time zone to be the system time zone.
5102 * This needs to be done because the system time zone could have changed after the
5103 * the spawning of this process. Without doing this this process would have the incorrect
5106 TimeZone.setDefault(null);
5109 * Set the LocaleList. This may change once we create the App Context.
5111 LocaleList.setDefault(data.config.getLocales());
5113 synchronized (mResourcesManager) {
5115 * Update the system configuration since its preloaded and might not
5116 * reflect configuration changes. The configuration object passed
5117 * in AppBindData can be safely assumed to be up to date
5119 mResourcesManager.applyConfigurationToResourcesLocked(data.config, data.compatInfo);
5120 mCurDefaultDisplayDpi = data.config.densityDpi;
5122 // This calls mResourcesManager so keep it within the synchronized block.
5123 applyCompatConfiguration(mCurDefaultDisplayDpi);
5126 data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
5129 * Switch this process to density compatibility mode if needed.
5131 if ((data.appInfo.flags&ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES)
5133 mDensityCompatMode = true;
5134 Bitmap.setDefaultDensity(DisplayMetrics.DENSITY_DEFAULT);
5136 updateDefaultDensity();
5138 final boolean is24Hr = "24".equals(mCoreSettings.getString(Settings.System.TIME_12_24));
5139 DateFormat.set24HourTimePref(is24Hr);
5141 View.mDebugViewAttributes =
5142 mCoreSettings.getInt(Settings.Global.DEBUG_VIEW_ATTRIBUTES, 0) != 0;
5145 * For system applications on userdebug/eng builds, log stack
5146 * traces of disk and network access to dropbox for analysis.
5148 if ((data.appInfo.flags &
5149 (ApplicationInfo.FLAG_SYSTEM |
5150 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0) {
5151 StrictMode.conditionallyEnableDebugLogging();
5155 * For apps targetting Honeycomb or later, we don't allow network usage
5156 * on the main event loop / UI thread. This is what ultimately throws
5157 * {@link NetworkOnMainThreadException}.
5159 if (data.appInfo.targetSdkVersion >= Build.VERSION_CODES.HONEYCOMB) {
5160 StrictMode.enableDeathOnNetwork();
5164 * For apps targetting N or later, we don't allow file:// Uri exposure.
5165 * This is what ultimately throws {@link FileUriExposedException}.
5167 if (data.appInfo.targetSdkVersion >= Build.VERSION_CODES.N) {
5168 StrictMode.enableDeathOnFileUriExposure();
5171 NetworkSecurityPolicy.getInstance().setCleartextTrafficPermitted(
5172 (data.appInfo.flags & ApplicationInfo.FLAG_USES_CLEARTEXT_TRAFFIC) != 0);
5174 if (data.debugMode != IApplicationThread.DEBUG_OFF) {
5175 // XXX should have option to change the port.
5176 Debug.changeDebugPort(8100);
5177 if (data.debugMode == IApplicationThread.DEBUG_WAIT) {
5178 Slog.w(TAG, "Application " + data.info.getPackageName()
5179 + " is waiting for the debugger on port 8100...");
5181 IActivityManager mgr = ActivityManagerNative.getDefault();
5183 mgr.showWaitingForDebugger(mAppThread, true);
5184 } catch (RemoteException ex) {
5185 throw ex.rethrowFromSystemServer();
5188 Debug.waitForDebugger();
5191 mgr.showWaitingForDebugger(mAppThread, false);
5192 } catch (RemoteException ex) {
5193 throw ex.rethrowFromSystemServer();
5197 Slog.w(TAG, "Application " + data.info.getPackageName()
5198 + " can be debugged on port 8100...");
5202 // Allow application-generated systrace messages if we're debuggable.
5203 boolean isAppDebuggable = (data.appInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
5204 Trace.setAppTracingAllowed(isAppDebuggable);
5205 if (isAppDebuggable && data.enableBinderTracking) {
5206 Binder.enableTracing();
5210 * Initialize the default http proxy in this process for the reasons we set the time zone.
5212 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Setup proxies");
5213 final IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE);
5215 // In pre-boot mode (doing initial launch to collect password), not
5216 // all system is up. This includes the connectivity service, so don't
5217 // crash if we can't get it.
5218 final IConnectivityManager service = IConnectivityManager.Stub.asInterface(b);
5220 final ProxyInfo proxyInfo = service.getProxyForNetwork(null);
5221 Proxy.setHttpProxySystemProperty(proxyInfo);
5222 } catch (RemoteException e) {
5223 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
5224 throw e.rethrowFromSystemServer();
5227 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
5229 // Instrumentation info affects the class loader, so load it before
5230 // setting up the app context.
5231 final InstrumentationInfo ii;
5232 if (data.instrumentationName != null) {
5234 ii = new ApplicationPackageManager(null, getPackageManager())
5235 .getInstrumentationInfo(data.instrumentationName, 0);
5236 } catch (PackageManager.NameNotFoundException e) {
5237 throw new RuntimeException(
5238 "Unable to find instrumentation info for: " + data.instrumentationName);
5241 mInstrumentationPackageName = ii.packageName;
5242 mInstrumentationAppDir = ii.sourceDir;
5243 mInstrumentationSplitAppDirs = ii.splitSourceDirs;
5244 mInstrumentationLibDir = getInstrumentationLibrary(data.appInfo, ii);
5245 mInstrumentedAppDir = data.info.getAppDir();
5246 mInstrumentedSplitAppDirs = data.info.getSplitAppDirs();
5247 mInstrumentedLibDir = data.info.getLibDir();
5252 final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);
5253 updateLocaleListFromAppContext(appContext,
5254 mResourcesManager.getConfiguration().getLocales());
5256 if (!Process.isIsolated() && !"android".equals(appContext.getPackageName())) {
5257 // This cache location probably points at credential-encrypted
5258 // storage which may not be accessible yet; assign it anyway instead
5259 // of pointing at device-encrypted storage.
5260 final File cacheDir = appContext.getCacheDir();
5261 if (cacheDir != null) {
5262 // Provide a usable directory for temporary files
5263 System.setProperty("java.io.tmpdir", cacheDir.getAbsolutePath());
5265 Log.v(TAG, "Unable to initialize \"java.io.tmpdir\" property "
5266 + "due to missing cache directory");
5269 // Setup a location to store generated/compiled graphics code.
5270 final Context deviceContext = appContext.createDeviceProtectedStorageContext();
5271 final File codeCacheDir = deviceContext.getCodeCacheDir();
5272 if (codeCacheDir != null) {
5273 setupGraphicsSupport(data.info, codeCacheDir);
5275 Log.e(TAG, "Unable to setupGraphicsSupport due to missing code-cache directory");
5279 // Install the Network Security Config Provider. This must happen before the application
5280 // code is loaded to prevent issues with instances of TLS objects being created before
5281 // the provider is installed.
5282 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "NetworkSecurityConfigProvider.install");
5283 NetworkSecurityConfigProvider.install(appContext);
5284 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
5286 // Continue loading instrumentation.
5288 final ApplicationInfo instrApp = new ApplicationInfo();
5289 ii.copyTo(instrApp);
5290 instrApp.initForUser(UserHandle.myUserId());
5291 final LoadedApk pi = getPackageInfo(instrApp, data.compatInfo,
5292 appContext.getClassLoader(), false, true, false);
5293 final ContextImpl instrContext = ContextImpl.createAppContext(this, pi);
5296 final ClassLoader cl = instrContext.getClassLoader();
5297 mInstrumentation = (Instrumentation)
5298 cl.loadClass(data.instrumentationName.getClassName()).newInstance();
5299 } catch (Exception e) {
5300 throw new RuntimeException(
5301 "Unable to instantiate instrumentation "
5302 + data.instrumentationName + ": " + e.toString(), e);
5305 final ComponentName component = new ComponentName(ii.packageName, ii.name);
5306 mInstrumentation.init(this, instrContext, appContext, component,
5307 data.instrumentationWatcher, data.instrumentationUiAutomationConnection);
5309 if (mProfiler.profileFile != null && !ii.handleProfiling
5310 && mProfiler.profileFd == null) {
5311 mProfiler.handlingProfiling = true;
5312 final File file = new File(mProfiler.profileFile);
5313 file.getParentFile().mkdirs();
5314 Debug.startMethodTracing(file.toString(), 8 * 1024 * 1024);
5317 mInstrumentation = new Instrumentation();
5320 if ((data.appInfo.flags&ApplicationInfo.FLAG_LARGE_HEAP) != 0) {
5321 dalvik.system.VMRuntime.getRuntime().clearGrowthLimit();
5323 // Small heap, clamp to the current growth limit and let the heap release
5324 // pages after the growth limit to the non growth limit capacity. b/18387825
5325 dalvik.system.VMRuntime.getRuntime().clampGrowthLimit();
5328 // Allow disk access during application and provider setup. This could
5329 // block processing ordered broadcasts, but later processing would
5330 // probably end up doing the same disk access.
5331 final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskWrites();
5333 // If the app is being launched for full backup or restore, bring it up in
5334 // a restricted environment with the base application class.
5335 Application app = data.info.makeApplication(data.restrictedBackupMode, null);
5336 mInitialApplication = app;
5338 // don't bring up providers in restricted mode; they may depend on the
5339 // app's custom Application class
5340 if (!data.restrictedBackupMode) {
5341 if (!ArrayUtils.isEmpty(data.providers)) {
5342 installContentProviders(app, data.providers);
5343 // For process that contains content providers, we want to
5344 // ensure that the JIT is enabled "at some point".
5345 mH.sendEmptyMessageDelayed(H.ENABLE_JIT, 10*1000);
5349 // Do this after providers, since instrumentation tests generally start their
5350 // test thread at this point, and we don't want that racing.
5352 mInstrumentation.onCreate(data.instrumentationArgs);
5354 catch (Exception e) {
5355 throw new RuntimeException(
5356 "Exception thrown in onCreate() of "
5357 + data.instrumentationName + ": " + e.toString(), e);
5361 mInstrumentation.callApplicationOnCreate(app);
5362 } catch (Exception e) {
5363 if (!mInstrumentation.onException(app, e)) {
5364 throw new RuntimeException(
5365 "Unable to create application " + app.getClass().getName()
5366 + ": " + e.toString(), e);
5370 StrictMode.setThreadPolicy(savedPolicy);
5374 /*package*/ final void finishInstrumentation(int resultCode, Bundle results) {
5375 IActivityManager am = ActivityManagerNative.getDefault();
5376 if (mProfiler.profileFile != null && mProfiler.handlingProfiling
5377 && mProfiler.profileFd == null) {
5378 Debug.stopMethodTracing();
5380 //Slog.i(TAG, "am: " + ActivityManagerNative.getDefault()
5381 // + ", app thr: " + mAppThread);
5383 am.finishInstrumentation(mAppThread, resultCode, results);
5384 } catch (RemoteException ex) {
5385 throw ex.rethrowFromSystemServer();
5389 private void installContentProviders(
5390 Context context, List<ProviderInfo> providers) {
5391 final ArrayList<IActivityManager.ContentProviderHolder> results =
5392 new ArrayList<IActivityManager.ContentProviderHolder>();
5394 for (ProviderInfo cpi : providers) {
5395 if (DEBUG_PROVIDER) {
5396 StringBuilder buf = new StringBuilder(128);
5398 buf.append(cpi.authority);
5400 buf.append(cpi.name);
5401 Log.i(TAG, buf.toString());
5403 IActivityManager.ContentProviderHolder cph = installProvider(context, null, cpi,
5404 false /*noisy*/, true /*noReleaseNeeded*/, true /*stable*/);
5406 cph.noReleaseNeeded = true;
5412 ActivityManagerNative.getDefault().publishContentProviders(
5413 getApplicationThread(), results);
5414 } catch (RemoteException ex) {
5415 throw ex.rethrowFromSystemServer();
5419 public final IContentProvider acquireProvider(
5420 Context c, String auth, int userId, boolean stable) {
5421 final IContentProvider provider = acquireExistingProvider(c, auth, userId, stable);
5422 if (provider != null) {
5426 // There is a possible race here. Another thread may try to acquire
5427 // the same provider at the same time. When this happens, we want to ensure
5428 // that the first one wins.
5429 // Note that we cannot hold the lock while acquiring and installing the
5430 // provider since it might take a long time to run and it could also potentially
5431 // be re-entrant in the case where the provider is in the same process.
5432 IActivityManager.ContentProviderHolder holder = null;
5434 holder = ActivityManagerNative.getDefault().getContentProvider(
5435 getApplicationThread(), auth, userId, stable);
5436 } catch (RemoteException ex) {
5437 throw ex.rethrowFromSystemServer();
5439 if (holder == null) {
5440 Slog.e(TAG, "Failed to find provider info for " + auth);
5444 // Install provider will increment the reference count for us, and break
5445 // any ties in the race.
5446 holder = installProvider(c, holder, holder.info,
5447 true /*noisy*/, holder.noReleaseNeeded, stable);
5448 return holder.provider;
5451 private final void incProviderRefLocked(ProviderRefCount prc, boolean stable) {
5453 prc.stableCount += 1;
5454 if (prc.stableCount == 1) {
5455 // We are acquiring a new stable reference on the provider.
5457 if (prc.removePending) {
5458 // We have a pending remove operation, which is holding the
5459 // last unstable reference. At this point we are converting
5460 // that unstable reference to our new stable reference.
5462 // Cancel the removal of the provider.
5463 if (DEBUG_PROVIDER) {
5464 Slog.v(TAG, "incProviderRef: stable "
5465 + "snatched provider from the jaws of death");
5467 prc.removePending = false;
5468 // There is a race! It fails to remove the message, which
5469 // will be handled in completeRemoveProvider().
5470 mH.removeMessages(H.REMOVE_PROVIDER, prc);
5475 if (DEBUG_PROVIDER) {
5476 Slog.v(TAG, "incProviderRef Now stable - "
5477 + prc.holder.info.name + ": unstableDelta="
5480 ActivityManagerNative.getDefault().refContentProvider(
5481 prc.holder.connection, 1, unstableDelta);
5482 } catch (RemoteException e) {
5483 //do nothing content provider object is dead any way
5487 prc.unstableCount += 1;
5488 if (prc.unstableCount == 1) {
5489 // We are acquiring a new unstable reference on the provider.
5490 if (prc.removePending) {
5491 // Oh look, we actually have a remove pending for the
5492 // provider, which is still holding the last unstable
5493 // reference. We just need to cancel that to take new
5494 // ownership of the reference.
5495 if (DEBUG_PROVIDER) {
5496 Slog.v(TAG, "incProviderRef: unstable "
5497 + "snatched provider from the jaws of death");
5499 prc.removePending = false;
5500 mH.removeMessages(H.REMOVE_PROVIDER, prc);
5502 // First unstable ref, increment our count in the
5503 // activity manager.
5505 if (DEBUG_PROVIDER) {
5506 Slog.v(TAG, "incProviderRef: Now unstable - "
5507 + prc.holder.info.name);
5509 ActivityManagerNative.getDefault().refContentProvider(
5510 prc.holder.connection, 0, 1);
5511 } catch (RemoteException e) {
5512 //do nothing content provider object is dead any way
5519 public final IContentProvider acquireExistingProvider(
5520 Context c, String auth, int userId, boolean stable) {
5521 synchronized (mProviderMap) {
5522 final ProviderKey key = new ProviderKey(auth, userId);
5523 final ProviderClientRecord pr = mProviderMap.get(key);
5528 IContentProvider provider = pr.mProvider;
5529 IBinder jBinder = provider.asBinder();
5530 if (!jBinder.isBinderAlive()) {
5531 // The hosting process of the provider has died; we can't
5533 Log.i(TAG, "Acquiring provider " + auth + " for user " + userId
5534 + ": existing object's process dead");
5535 handleUnstableProviderDiedLocked(jBinder, true);
5539 // Only increment the ref count if we have one. If we don't then the
5540 // provider is not reference counted and never needs to be released.
5541 ProviderRefCount prc = mProviderRefCountMap.get(jBinder);
5543 incProviderRefLocked(prc, stable);
5549 public final boolean releaseProvider(IContentProvider provider, boolean stable) {
5550 if (provider == null) {
5554 IBinder jBinder = provider.asBinder();
5555 synchronized (mProviderMap) {
5556 ProviderRefCount prc = mProviderRefCountMap.get(jBinder);
5558 // The provider has no ref count, no release is needed.
5562 boolean lastRef = false;
5564 if (prc.stableCount == 0) {
5565 if (DEBUG_PROVIDER) Slog.v(TAG,
5566 "releaseProvider: stable ref count already 0, how?");
5569 prc.stableCount -= 1;
5570 if (prc.stableCount == 0) {
5571 // What we do at this point depends on whether there are
5572 // any unstable refs left: if there are, we just tell the
5573 // activity manager to decrement its stable count; if there
5574 // aren't, we need to enqueue this provider to be removed,
5575 // and convert to holding a single unstable ref while
5577 lastRef = prc.unstableCount == 0;
5579 if (DEBUG_PROVIDER) {
5580 Slog.v(TAG, "releaseProvider: No longer stable w/lastRef="
5581 + lastRef + " - " + prc.holder.info.name);
5583 ActivityManagerNative.getDefault().refContentProvider(
5584 prc.holder.connection, -1, lastRef ? 1 : 0);
5585 } catch (RemoteException e) {
5586 //do nothing content provider object is dead any way
5590 if (prc.unstableCount == 0) {
5591 if (DEBUG_PROVIDER) Slog.v(TAG,
5592 "releaseProvider: unstable ref count already 0, how?");
5595 prc.unstableCount -= 1;
5596 if (prc.unstableCount == 0) {
5597 // If this is the last reference, we need to enqueue
5598 // this provider to be removed instead of telling the
5599 // activity manager to remove it at this point.
5600 lastRef = prc.stableCount == 0;
5603 if (DEBUG_PROVIDER) {
5604 Slog.v(TAG, "releaseProvider: No longer unstable - "
5605 + prc.holder.info.name);
5607 ActivityManagerNative.getDefault().refContentProvider(
5608 prc.holder.connection, 0, -1);
5609 } catch (RemoteException e) {
5610 //do nothing content provider object is dead any way
5617 if (!prc.removePending) {
5618 // Schedule the actual remove asynchronously, since we don't know the context
5619 // this will be called in.
5620 // TODO: it would be nice to post a delayed message, so
5621 // if we come back and need the same provider quickly
5622 // we will still have it available.
5623 if (DEBUG_PROVIDER) {
5624 Slog.v(TAG, "releaseProvider: Enqueueing pending removal - "
5625 + prc.holder.info.name);
5627 prc.removePending = true;
5628 Message msg = mH.obtainMessage(H.REMOVE_PROVIDER, prc);
5629 mH.sendMessage(msg);
5631 Slog.w(TAG, "Duplicate remove pending of provider " + prc.holder.info.name);
5638 final void completeRemoveProvider(ProviderRefCount prc) {
5639 synchronized (mProviderMap) {
5640 if (!prc.removePending) {
5641 // There was a race! Some other client managed to acquire
5642 // the provider before the removal was completed.
5643 // Abort the removal. We will do it later.
5644 if (DEBUG_PROVIDER) Slog.v(TAG, "completeRemoveProvider: lost the race, "
5645 + "provider still in use");
5649 // More complicated race!! Some client managed to acquire the
5650 // provider and release it before the removal was completed.
5651 // Continue the removal, and abort the next remove message.
5652 prc.removePending = false;
5654 final IBinder jBinder = prc.holder.provider.asBinder();
5655 ProviderRefCount existingPrc = mProviderRefCountMap.get(jBinder);
5656 if (existingPrc == prc) {
5657 mProviderRefCountMap.remove(jBinder);
5660 for (int i=mProviderMap.size()-1; i>=0; i--) {
5661 ProviderClientRecord pr = mProviderMap.valueAt(i);
5662 IBinder myBinder = pr.mProvider.asBinder();
5663 if (myBinder == jBinder) {
5664 mProviderMap.removeAt(i);
5670 if (DEBUG_PROVIDER) {
5671 Slog.v(TAG, "removeProvider: Invoking ActivityManagerNative."
5672 + "removeContentProvider(" + prc.holder.info.name + ")");
5674 ActivityManagerNative.getDefault().removeContentProvider(
5675 prc.holder.connection, false);
5676 } catch (RemoteException e) {
5677 //do nothing content provider object is dead any way
5681 final void handleUnstableProviderDied(IBinder provider, boolean fromClient) {
5682 synchronized (mProviderMap) {
5683 handleUnstableProviderDiedLocked(provider, fromClient);
5687 final void handleUnstableProviderDiedLocked(IBinder provider, boolean fromClient) {
5688 ProviderRefCount prc = mProviderRefCountMap.get(provider);
5690 if (DEBUG_PROVIDER) Slog.v(TAG, "Cleaning up dead provider "
5691 + provider + " " + prc.holder.info.name);
5692 mProviderRefCountMap.remove(provider);
5693 for (int i=mProviderMap.size()-1; i>=0; i--) {
5694 ProviderClientRecord pr = mProviderMap.valueAt(i);
5695 if (pr != null && pr.mProvider.asBinder() == provider) {
5696 Slog.i(TAG, "Removing dead content provider:" + pr.mProvider.toString());
5697 mProviderMap.removeAt(i);
5702 // We found out about this due to execution in our client
5703 // code. Tell the activity manager about it now, to ensure
5704 // that the next time we go to do anything with the provider
5705 // it knows it is dead (so we don't race with its death
5708 ActivityManagerNative.getDefault().unstableProviderDied(
5709 prc.holder.connection);
5710 } catch (RemoteException e) {
5711 //do nothing content provider object is dead any way
5717 final void appNotRespondingViaProvider(IBinder provider) {
5718 synchronized (mProviderMap) {
5719 ProviderRefCount prc = mProviderRefCountMap.get(provider);
5722 ActivityManagerNative.getDefault()
5723 .appNotRespondingViaProvider(prc.holder.connection);
5724 } catch (RemoteException e) {
5725 throw e.rethrowFromSystemServer();
5731 private ProviderClientRecord installProviderAuthoritiesLocked(IContentProvider provider,
5732 ContentProvider localProvider, IActivityManager.ContentProviderHolder holder) {
5733 final String auths[] = holder.info.authority.split(";");
5734 final int userId = UserHandle.getUserId(holder.info.applicationInfo.uid);
5736 final ProviderClientRecord pcr = new ProviderClientRecord(
5737 auths, provider, localProvider, holder);
5738 for (String auth : auths) {
5739 final ProviderKey key = new ProviderKey(auth, userId);
5740 final ProviderClientRecord existing = mProviderMap.get(key);
5741 if (existing != null) {
5742 Slog.w(TAG, "Content provider " + pcr.mHolder.info.name
5743 + " already published as " + auth);
5745 mProviderMap.put(key, pcr);
5752 * Installs the provider.
5754 * Providers that are local to the process or that come from the system server
5755 * may be installed permanently which is indicated by setting noReleaseNeeded to true.
5756 * Other remote providers are reference counted. The initial reference count
5757 * for all reference counted providers is one. Providers that are not reference
5758 * counted do not have a reference count (at all).
5760 * This method detects when a provider has already been installed. When this happens,
5761 * it increments the reference count of the existing provider (if appropriate)
5762 * and returns the existing provider. This can happen due to concurrent
5763 * attempts to acquire the same provider.
5765 private IActivityManager.ContentProviderHolder installProvider(Context context,
5766 IActivityManager.ContentProviderHolder holder, ProviderInfo info,
5767 boolean noisy, boolean noReleaseNeeded, boolean stable) {
5768 ContentProvider localProvider = null;
5769 IContentProvider provider;
5770 if (holder == null || holder.provider == null) {
5771 if (DEBUG_PROVIDER || noisy) {
5772 Slog.d(TAG, "Loading provider " + info.authority + ": "
5776 ApplicationInfo ai = info.applicationInfo;
5777 if (context.getPackageName().equals(ai.packageName)) {
5779 } else if (mInitialApplication != null &&
5780 mInitialApplication.getPackageName().equals(ai.packageName)) {
5781 c = mInitialApplication;
5784 c = context.createPackageContext(ai.packageName,
5785 Context.CONTEXT_INCLUDE_CODE);
5786 } catch (PackageManager.NameNotFoundException e) {
5791 Slog.w(TAG, "Unable to get context for package " +
5793 " while loading content provider " +
5798 final java.lang.ClassLoader cl = c.getClassLoader();
5799 localProvider = (ContentProvider)cl.
5800 loadClass(info.name).newInstance();
5801 provider = localProvider.getIContentProvider();
5802 if (provider == null) {
5803 Slog.e(TAG, "Failed to instantiate class " +
5804 info.name + " from sourceDir " +
5805 info.applicationInfo.sourceDir);
5808 if (DEBUG_PROVIDER) Slog.v(
5809 TAG, "Instantiating local provider " + info.name);
5810 // XXX Need to create the correct context for this provider.
5811 localProvider.attachInfo(c, info);
5812 } catch (java.lang.Exception e) {
5813 if (!mInstrumentation.onException(null, e)) {
5814 throw new RuntimeException(
5815 "Unable to get provider " + info.name
5816 + ": " + e.toString(), e);
5821 provider = holder.provider;
5822 if (DEBUG_PROVIDER) Slog.v(TAG, "Installing external provider " + info.authority + ": "
5826 IActivityManager.ContentProviderHolder retHolder;
5828 synchronized (mProviderMap) {
5829 if (DEBUG_PROVIDER) Slog.v(TAG, "Checking to add " + provider
5830 + " / " + info.name);
5831 IBinder jBinder = provider.asBinder();
5832 if (localProvider != null) {
5833 ComponentName cname = new ComponentName(info.packageName, info.name);
5834 ProviderClientRecord pr = mLocalProvidersByName.get(cname);
5836 if (DEBUG_PROVIDER) {
5837 Slog.v(TAG, "installProvider: lost the race, "
5838 + "using existing local provider");
5840 provider = pr.mProvider;
5842 holder = new IActivityManager.ContentProviderHolder(info);
5843 holder.provider = provider;
5844 holder.noReleaseNeeded = true;
5845 pr = installProviderAuthoritiesLocked(provider, localProvider, holder);
5846 mLocalProviders.put(jBinder, pr);
5847 mLocalProvidersByName.put(cname, pr);
5849 retHolder = pr.mHolder;
5851 ProviderRefCount prc = mProviderRefCountMap.get(jBinder);
5853 if (DEBUG_PROVIDER) {
5854 Slog.v(TAG, "installProvider: lost the race, updating ref count");
5856 // We need to transfer our new reference to the existing
5857 // ref count, releasing the old one... but only if
5858 // release is needed (that is, it is not running in the
5860 if (!noReleaseNeeded) {
5861 incProviderRefLocked(prc, stable);
5863 ActivityManagerNative.getDefault().removeContentProvider(
5864 holder.connection, stable);
5865 } catch (RemoteException e) {
5866 //do nothing content provider object is dead any way
5870 ProviderClientRecord client = installProviderAuthoritiesLocked(
5871 provider, localProvider, holder);
5872 if (noReleaseNeeded) {
5873 prc = new ProviderRefCount(holder, client, 1000, 1000);
5876 ? new ProviderRefCount(holder, client, 1, 0)
5877 : new ProviderRefCount(holder, client, 0, 1);
5879 mProviderRefCountMap.put(jBinder, prc);
5881 retHolder = prc.holder;
5888 private void attach(boolean system) {
5889 sCurrentActivityThread = this;
5890 mSystemThread = system;
5892 ViewRootImpl.addFirstDrawHandler(new Runnable() {
5898 android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",
5899 UserHandle.myUserId());
5900 RuntimeInit.setApplicationObject(mAppThread.asBinder());
5901 final IActivityManager mgr = ActivityManagerNative.getDefault();
5903 mgr.attachApplication(mAppThread);
5904 } catch (RemoteException ex) {
5905 throw ex.rethrowFromSystemServer();
5907 // Watch for getting close to heap limit.
5908 BinderInternal.addGcWatcher(new Runnable() {
5909 @Override public void run() {
5910 if (!mSomeActivitiesChanged) {
5913 Runtime runtime = Runtime.getRuntime();
5914 long dalvikMax = runtime.maxMemory();
5915 long dalvikUsed = runtime.totalMemory() - runtime.freeMemory();
5916 if (dalvikUsed > ((3*dalvikMax)/4)) {
5917 if (DEBUG_MEMORY_TRIM) Slog.d(TAG, "Dalvik max=" + (dalvikMax/1024)
5918 + " total=" + (runtime.totalMemory()/1024)
5919 + " used=" + (dalvikUsed/1024));
5920 mSomeActivitiesChanged = false;
5922 mgr.releaseSomeActivities(mAppThread);
5923 } catch (RemoteException e) {
5924 throw e.rethrowFromSystemServer();
5930 // Don't set application object here -- if the system crashes,
5931 // we can't display an alert, we just want to die die die.
5932 android.ddm.DdmHandleAppName.setAppName("system_process",
5933 UserHandle.myUserId());
5935 mInstrumentation = new Instrumentation();
5936 ContextImpl context = ContextImpl.createAppContext(
5937 this, getSystemContext().mPackageInfo);
5938 mInitialApplication = context.mPackageInfo.makeApplication(true, null);
5939 mInitialApplication.onCreate();
5940 } catch (Exception e) {
5941 throw new RuntimeException(
5942 "Unable to instantiate Application():" + e.toString(), e);
5946 // add dropbox logging to libcore
5947 DropBox.setReporter(new DropBoxReporter());
5949 ViewRootImpl.addConfigCallback(new ComponentCallbacks2() {
5951 public void onConfigurationChanged(Configuration newConfig) {
5952 synchronized (mResourcesManager) {
5953 // We need to apply this change to the resources
5954 // immediately, because upon returning the view
5955 // hierarchy will be informed about it.
5956 if (mResourcesManager.applyConfigurationToResourcesLocked(newConfig, null)) {
5957 updateLocaleListFromAppContext(mInitialApplication.getApplicationContext(),
5958 mResourcesManager.getConfiguration().getLocales());
5960 // This actually changed the resources! Tell
5961 // everyone about it.
5962 if (mPendingConfiguration == null ||
5963 mPendingConfiguration.isOtherSeqNewer(newConfig)) {
5964 mPendingConfiguration = newConfig;
5966 sendMessage(H.CONFIGURATION_CHANGED, newConfig);
5972 public void onLowMemory() {
5975 public void onTrimMemory(int level) {
5980 public static ActivityThread systemMain() {
5981 // The system process on low-memory devices do not get to use hardware
5982 // accelerated drawing, since this can add too much overhead to the
5984 if (!ActivityManager.isHighEndGfx()) {
5985 ThreadedRenderer.disable(true);
5987 ThreadedRenderer.enableForegroundTrimming();
5989 ActivityThread thread = new ActivityThread();
5990 thread.attach(true);
5994 public final void installSystemProviders(List<ProviderInfo> providers) {
5995 if (providers != null) {
5996 installContentProviders(mInitialApplication, providers);
6000 public int getIntCoreSetting(String key, int defaultValue) {
6001 synchronized (mResourcesManager) {
6002 if (mCoreSettings != null) {
6003 return mCoreSettings.getInt(key, defaultValue);
6005 return defaultValue;
6009 private static class EventLoggingReporter implements EventLogger.Reporter {
6011 public void report (int code, Object... list) {
6012 EventLog.writeEvent(code, list);
6016 private class DropBoxReporter implements DropBox.Reporter {
6018 private DropBoxManager dropBox;
6020 public DropBoxReporter() {}
6023 public void addData(String tag, byte[] data, int flags) {
6024 ensureInitialized();
6025 dropBox.addData(tag, data, flags);
6029 public void addText(String tag, String data) {
6030 ensureInitialized();
6031 dropBox.addText(tag, data);
6034 private synchronized void ensureInitialized() {
6035 if (dropBox == null) {
6036 dropBox = (DropBoxManager) getSystemContext().getSystemService(Context.DROPBOX_SERVICE);
6041 public static void main(String[] args) {
6042 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");
6043 SamplingProfilerIntegration.start();
6045 // CloseGuard defaults to true and can be quite spammy. We
6046 // disable it here, but selectively enable it later (via
6047 // StrictMode) on debug builds, but using DropBox, not logs.
6048 CloseGuard.setEnabled(false);
6050 Environment.initForCurrentUser();
6052 // Set the reporter for event logging in libcore
6053 EventLogger.setReporter(new EventLoggingReporter());
6055 // Make sure TrustedCertificateStore looks in the right place for CA certificates
6056 final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
6057 TrustedCertificateStore.setDefaultUserDirectory(configDir);
6059 Process.setArgV0("<pre-initialized>");
6061 Looper.prepareMainLooper();
6063 ActivityThread thread = new ActivityThread();
6064 thread.attach(false);
6066 if (sMainThreadHandler == null) {
6067 sMainThreadHandler = thread.getHandler();
6071 Looper.myLooper().setMessageLogging(new
6072 LogPrinter(Log.DEBUG, "ActivityThread"));
6075 // End of event ActivityThreadMain.
6076 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6079 throw new RuntimeException("Main thread loop unexpectedly exited");