OSDN Git Service

DO NOT MERGE. Grant MMS Uri permissions as the calling UID.
[android-x86/frameworks-base.git] / core / java / android / app / ActivityThread.java
1 /*
2  * Copyright (C) 2006 The Android Open Source Project
3  *
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
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 package android.app;
18
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;
111
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;
124
125 import java.io.File;
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;
140
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;
149
150 final class RemoteServiceException extends AndroidRuntimeException {
151     public RemoteServiceException(String msg) {
152         super(msg);
153     }
154 }
155
156 /**
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
160  * manager requests.
161  *
162  * {@hide}
163  */
164 public final class ActivityThread {
165     /** @hide */
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;
170     /** @hide */
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;
184
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;
191
192     // Details for pausing activity.
193     private static final int USER_LEAVING = 1;
194     private static final int DONT_REPORT = 2;
195
196     // Whether to invoke an activity callback after delivering new configuration.
197     private static final boolean REPORT_TO_ACTIVITY = true;
198
199     private ContextImpl mSystemContext;
200
201     static volatile IPackageManager sPackageManager;
202
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;
216     Profiler mProfiler;
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;
239
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;
262
263     private final ResourcesManager mResourcesManager;
264
265     private static final class ProviderKey {
266         final String authority;
267         final int userId;
268
269         public ProviderKey(String authority, int userId) {
270             this.authority = authority;
271             this.userId = userId;
272         }
273
274         @Override
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;
279             }
280             return false;
281         }
282
283         @Override
284         public int hashCode() {
285             return ((authority != null) ? authority.hashCode() : 0) ^ userId;
286         }
287     }
288
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>();
298
299     final ArrayMap<Activity, ArrayList<OnActivityPausedListener>> mOnPauseListeners
300         = new ArrayMap<Activity, ArrayList<OnActivityPausedListener>>();
301
302     final GcIdler mGcIdler = new GcIdler();
303     boolean mGcIdlerScheduled = false;
304
305     static volatile Handler sMainThreadHandler;  // set once in main()
306
307     Bundle mCoreSettings = null;
308
309     static final class ActivityClientRecord {
310         IBinder token;
311         int ident;
312         Intent intent;
313         String referrer;
314         IVoiceInteractor voiceInteractor;
315         Bundle state;
316         PersistableBundle persistentState;
317         Activity activity;
318         Window window;
319         Activity parent;
320         String embeddedID;
321         Activity.NonConfigurationInstances lastNonConfigurationInstances;
322         boolean paused;
323         boolean stopped;
324         boolean hideForNow;
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;
331
332         ProfilerInfo profilerInfo;
333
334         ActivityInfo activityInfo;
335         CompatibilityInfo compatInfo;
336         LoadedApk packageInfo;
337
338         List<ResultInfo> pendingResults;
339         List<ReferrerIntent> pendingIntents;
340
341         boolean startsNotResumed;
342         boolean isForward;
343         int pendingConfigChanges;
344         boolean onlyLocalRequest;
345
346         Window mPendingRemoveWindow;
347         WindowManager mPendingRemoveWindowManager;
348         boolean mPreserveWindow;
349
350         // Set for relaunch requests, indicates the order number of the relaunch operation, so it
351         // can be compared with other lifecycle operations.
352         int relaunchSeq = 0;
353
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;
357
358         ActivityClientRecord() {
359             parent = null;
360             embeddedID = null;
361             paused = false;
362             stopped = false;
363             hideForNow = false;
364             nextIdle = null;
365         }
366
367         public boolean isPreHoneycomb() {
368             if (activity != null) {
369                 return activity.getApplicationInfo().targetSdkVersion
370                         < android.os.Build.VERSION_CODES.HONEYCOMB;
371             }
372             return false;
373         }
374
375         public boolean isPersistable() {
376             return activityInfo.persistableMode == ActivityInfo.PERSIST_ACROSS_REBOOTS;
377         }
378
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())
385                 + "}";
386         }
387
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);
409                 sb.append("}");
410             }
411             sb.append("}");
412             return sb.toString();
413         }
414     }
415
416     final class ProviderClientRecord {
417         final String[] mNames;
418         final IContentProvider mProvider;
419         final ContentProvider mLocalProvider;
420         final IActivityManager.ContentProviderHolder mHolder;
421
422         ProviderClientRecord(String[] names, IContentProvider provider,
423                 ContentProvider localProvider,
424                 IActivityManager.ContentProviderHolder holder) {
425             mNames = names;
426             mProvider = provider;
427             mLocalProvider = localProvider;
428             mHolder = holder;
429         }
430     }
431
432     static final class NewIntentData {
433         List<ReferrerIntent> intents;
434         IBinder token;
435         public String toString() {
436             return "NewIntentData{intents=" + intents + " token=" + token + "}";
437         }
438     }
439
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;
446         }
447
448         Intent intent;
449         ActivityInfo info;
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) + "}";
456         }
457     }
458
459     static final class CreateBackupAgentData {
460         ApplicationInfo appInfo;
461         CompatibilityInfo compatInfo;
462         int backupMode;
463         public String toString() {
464             return "CreateBackupAgentData{appInfo=" + appInfo
465                     + " backupAgent=" + appInfo.backupAgentName
466                     + " mode=" + backupMode + "}";
467         }
468     }
469
470     static final class CreateServiceData {
471         IBinder token;
472         ServiceInfo info;
473         CompatibilityInfo compatInfo;
474         Intent intent;
475         public String toString() {
476             return "CreateServiceData{token=" + token + " className="
477             + info.name + " packageName=" + info.packageName
478             + " intent=" + intent + "}";
479         }
480     }
481
482     static final class BindServiceData {
483         IBinder token;
484         Intent intent;
485         boolean rebind;
486         public String toString() {
487             return "BindServiceData{token=" + token + " intent=" + intent + "}";
488         }
489     }
490
491     static final class ServiceArgsData {
492         IBinder token;
493         boolean taskRemoved;
494         int startId;
495         int flags;
496         Intent args;
497         public String toString() {
498             return "ServiceArgsData{token=" + token + " startId=" + startId
499             + " args=" + args + "}";
500         }
501     }
502
503     static final class AppBindData {
504         LoadedApk info;
505         String processName;
506         ApplicationInfo appInfo;
507         List<ProviderInfo> providers;
508         ComponentName instrumentationName;
509         Bundle instrumentationArgs;
510         IInstrumentationWatcher instrumentationWatcher;
511         IUiAutomationConnection instrumentationUiAutomationConnection;
512         int debugMode;
513         boolean enableBinderTracking;
514         boolean trackAllocation;
515         boolean restrictedBackupMode;
516         boolean persistent;
517         Configuration config;
518         CompatibilityInfo compatInfo;
519
520         /** Initial values for {@link Profiler}. */
521         ProfilerInfo initProfilerInfo;
522
523         public String toString() {
524             return "AppBindData{appInfo=" + appInfo + "}";
525         }
526     }
527
528     static final class Profiler {
529         String profileFile;
530         ParcelFileDescriptor profileFd;
531         int samplingInterval;
532         boolean autoStopProfiler;
533         boolean profiling;
534         boolean handlingProfiling;
535         public void setProfiler(ProfilerInfo profilerInfo) {
536             ParcelFileDescriptor fd = profilerInfo.profileFd;
537             if (profiling) {
538                 if (fd != null) {
539                     try {
540                         fd.close();
541                     } catch (IOException e) {
542                         // Ignore
543                     }
544                 }
545                 return;
546             }
547             if (profileFd != null) {
548                 try {
549                     profileFd.close();
550                 } catch (IOException e) {
551                     // Ignore
552                 }
553             }
554             profileFile = profilerInfo.profileFile;
555             profileFd = fd;
556             samplingInterval = profilerInfo.samplingInterval;
557             autoStopProfiler = profilerInfo.autoStopProfiler;
558         }
559         public void startProfiling() {
560             if (profileFd == null || profiling) {
561                 return;
562             }
563             try {
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);
567                 profiling = true;
568             } catch (RuntimeException e) {
569                 Slog.w(TAG, "Profiling failed on path " + profileFile);
570                 try {
571                     profileFd.close();
572                     profileFd = null;
573                 } catch (IOException e2) {
574                     Slog.w(TAG, "Failure closing profile fd", e2);
575                 }
576             }
577         }
578         public void stopProfiling() {
579             if (profiling) {
580                 profiling = false;
581                 Debug.stopMethodTracing();
582                 if (profileFd != null) {
583                     try {
584                         profileFd.close();
585                     } catch (IOException e) {
586                     }
587                 }
588                 profileFd = null;
589                 profileFile = null;
590             }
591         }
592     }
593
594     static final class DumpComponentInfo {
595         ParcelFileDescriptor fd;
596         IBinder token;
597         String prefix;
598         String[] args;
599     }
600
601     static final class ResultData {
602         IBinder token;
603         List<ResultInfo> results;
604         public String toString() {
605             return "ResultData{token=" + token + " results" + results + "}";
606         }
607     }
608
609     static final class ContextCleanupInfo {
610         ContextImpl context;
611         String what;
612         String who;
613     }
614
615     static final class DumpHeapData {
616         String path;
617         ParcelFileDescriptor fd;
618     }
619
620     static final class UpdateCompatibilityData {
621         String pkg;
622         CompatibilityInfo info;
623     }
624
625     static final class RequestAssistContextExtras {
626         IBinder activityToken;
627         IBinder requestToken;
628         int requestType;
629         int sessionId;
630     }
631
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;
638         }
639     }
640
641     private native void dumpGraphicsInfo(FileDescriptor fd);
642
643     private class ApplicationThread extends ApplicationThreadNative {
644         private static final String DB_INFO_FORMAT = "  %8s %8s %14s %14s  %s";
645
646         private int mLastProcessState = -1;
647
648         private void updatePendingConfiguration(Configuration config) {
649             synchronized (mResourcesManager) {
650                 if (mPendingConfiguration == null ||
651                         mPendingConfiguration.isOtherSeqNewer(config)) {
652                     mPendingConfiguration = config;
653                 }
654             }
655         }
656
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);
662             sendMessage(
663                     finished ? H.PAUSE_ACTIVITY_FINISHING : H.PAUSE_ACTIVITY,
664                     token,
665                     (userLeaving ? USER_LEAVING : 0) | (dontReport ? DONT_REPORT : 0),
666                     configChanges,
667                     seq);
668         }
669
670         public final void scheduleStopActivity(IBinder token, boolean showWindow,
671                 int configChanges) {
672             int seq = getLifecycleSeq();
673             if (DEBUG_ORDER) Slog.d(TAG, "stopActivity " + ActivityThread.this
674                     + " operation received seq: " + seq);
675             sendMessage(
676                 showWindow ? H.STOP_ACTIVITY_SHOW : H.STOP_ACTIVITY_HIDE,
677                 token, 0, configChanges, seq);
678         }
679
680         public final void scheduleWindowVisibility(IBinder token, boolean showWindow) {
681             sendMessage(
682                 showWindow ? H.SHOW_WINDOW : H.HIDE_WINDOW,
683                 token);
684         }
685
686         public final void scheduleSleeping(IBinder token, boolean sleeping) {
687             sendMessage(H.SLEEPING, token, sleeping ? 1 : 0);
688         }
689
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);
697         }
698
699         public final void scheduleSendResult(IBinder token, List<ResultInfo> results) {
700             ResultData res = new ResultData();
701             res.token = token;
702             res.results = results;
703             sendMessage(H.SEND_RESULT, res);
704         }
705
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)
708         @Override
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) {
715
716             updateProcessState(procState, false);
717
718             ActivityClientRecord r = new ActivityClientRecord();
719
720             r.token = token;
721             r.ident = ident;
722             r.intent = intent;
723             r.referrer = referrer;
724             r.voiceInteractor = voiceInteractor;
725             r.activityInfo = info;
726             r.compatInfo = compatInfo;
727             r.state = state;
728             r.persistentState = persistentState;
729
730             r.pendingResults = pendingResults;
731             r.pendingIntents = pendingNewIntents;
732
733             r.startsNotResumed = notResumed;
734             r.isForward = isForward;
735
736             r.profilerInfo = profilerInfo;
737
738             r.overrideConfig = overrideConfig;
739             updatePendingConfiguration(curConfig);
740
741             sendMessage(H.LAUNCH_ACTIVITY, r);
742         }
743
744         @Override
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);
751         }
752
753         public final void scheduleNewIntent(List<ReferrerIntent> intents, IBinder token) {
754             NewIntentData data = new NewIntentData();
755             data.intents = intents;
756             data.token = token;
757
758             sendMessage(H.NEW_INTENT, data);
759         }
760
761         public final void scheduleDestroyActivity(IBinder token, boolean finishing,
762                 int configChanges) {
763             sendMessage(H.DESTROY_ACTIVITY, token, finishing ? 1 : 0,
764                     configChanges);
765         }
766
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);
773             r.info = info;
774             r.compatInfo = compatInfo;
775             sendMessage(H.RECEIVER, r);
776         }
777
778         public final void scheduleCreateBackupAgent(ApplicationInfo app,
779                 CompatibilityInfo compatInfo, int backupMode) {
780             CreateBackupAgentData d = new CreateBackupAgentData();
781             d.appInfo = app;
782             d.compatInfo = compatInfo;
783             d.backupMode = backupMode;
784
785             sendMessage(H.CREATE_BACKUP_AGENT, d);
786         }
787
788         public final void scheduleDestroyBackupAgent(ApplicationInfo app,
789                 CompatibilityInfo compatInfo) {
790             CreateBackupAgentData d = new CreateBackupAgentData();
791             d.appInfo = app;
792             d.compatInfo = compatInfo;
793
794             sendMessage(H.DESTROY_BACKUP_AGENT, d);
795         }
796
797         public final void scheduleCreateService(IBinder token,
798                 ServiceInfo info, CompatibilityInfo compatInfo, int processState) {
799             updateProcessState(processState, false);
800             CreateServiceData s = new CreateServiceData();
801             s.token = token;
802             s.info = info;
803             s.compatInfo = compatInfo;
804
805             sendMessage(H.CREATE_SERVICE, s);
806         }
807
808         public final void scheduleBindService(IBinder token, Intent intent,
809                 boolean rebind, int processState) {
810             updateProcessState(processState, false);
811             BindServiceData s = new BindServiceData();
812             s.token = token;
813             s.intent = intent;
814             s.rebind = rebind;
815
816             if (DEBUG_SERVICE)
817                 Slog.v(TAG, "scheduleBindService token=" + token + " intent=" + intent + " uid="
818                         + Binder.getCallingUid() + " pid=" + Binder.getCallingPid());
819             sendMessage(H.BIND_SERVICE, s);
820         }
821
822         public final void scheduleUnbindService(IBinder token, Intent intent) {
823             BindServiceData s = new BindServiceData();
824             s.token = token;
825             s.intent = intent;
826
827             sendMessage(H.UNBIND_SERVICE, s);
828         }
829
830         public final void scheduleServiceArgs(IBinder token, boolean taskRemoved, int startId,
831             int flags ,Intent args) {
832             ServiceArgsData s = new ServiceArgsData();
833             s.token = token;
834             s.taskRemoved = taskRemoved;
835             s.startId = startId;
836             s.flags = flags;
837             s.args = args;
838
839             sendMessage(H.SERVICE_ARGS, s);
840         }
841
842         public final void scheduleStopService(IBinder token) {
843             sendMessage(H.STOP_SERVICE, token);
844         }
845
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) {
854
855             if (services != null) {
856                 // Setup the service cache in the ServiceManager
857                 ServiceManager.initServiceCache(services);
858             }
859
860             setCoreSettings(coreSettings);
861
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);
879         }
880
881         public final void scheduleExit() {
882             sendMessage(H.EXIT_APPLICATION, null);
883         }
884
885         public final void scheduleSuicide() {
886             sendMessage(H.SUICIDE, null);
887         }
888
889         public void scheduleConfigurationChanged(Configuration config) {
890             updatePendingConfiguration(config);
891             sendMessage(H.CONFIGURATION_CHANGED, config);
892         }
893
894         public void updateTimeZone() {
895             TimeZone.setDefault(null);
896         }
897
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();
904         }
905
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());
911             } else {
912                 Proxy.setHttpProxySystemProperty(host, port, exclList, pacFileUrl);
913             }
914         }
915
916         public void processInBackground() {
917             mH.removeMessages(H.GC_WHEN_IDLE);
918             mH.sendMessage(mH.obtainMessage(H.GC_WHEN_IDLE));
919         }
920
921         public void dumpService(FileDescriptor fd, IBinder servicetoken, String[] args) {
922             DumpComponentInfo data = new DumpComponentInfo();
923             try {
924                 data.fd = ParcelFileDescriptor.dup(fd);
925                 data.token = servicetoken;
926                 data.args = args;
927                 sendMessage(H.DUMP_SERVICE, data, 0, 0, true /*async*/);
928             } catch (IOException e) {
929                 Slog.w(TAG, "dumpService failed", e);
930             }
931         }
932
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);
942         }
943
944         @Override
945         public void scheduleLowMemory() {
946             sendMessage(H.LOW_MEMORY, null);
947         }
948
949         @Override
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);
954         }
955
956         @Override
957         public void profilerControl(boolean start, ProfilerInfo profilerInfo, int profileType) {
958             sendMessage(H.PROFILER_CONTROL, profilerInfo, start ? 1 : 0, profileType);
959         }
960
961         public void dumpHeap(boolean managed, String path, ParcelFileDescriptor fd) {
962             DumpHeapData dhd = new DumpHeapData();
963             dhd.path = path;
964             dhd.fd = fd;
965             sendMessage(H.DUMP_HEAP, dhd, managed ? 1 : 0, 0, true /*async*/);
966         }
967
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.
973             try {
974                 Process.setProcessGroup(Process.myPid(), group);
975             } catch (Exception e) {
976                 Slog.w(TAG, "Failed setting process group to " + group, e);
977             }
978         }
979
980         public void dispatchPackageBroadcast(int cmd, String[] packages) {
981             sendMessage(H.DISPATCH_PACKAGE_BROADCAST, packages, cmd);
982         }
983
984         public void scheduleCrash(String msg) {
985             sendMessage(H.SCHEDULE_CRASH, msg);
986         }
987
988         public void dumpActivity(FileDescriptor fd, IBinder activitytoken,
989                 String prefix, String[] args) {
990             DumpComponentInfo data = new DumpComponentInfo();
991             try {
992                 data.fd = ParcelFileDescriptor.dup(fd);
993                 data.token = activitytoken;
994                 data.prefix = prefix;
995                 data.args = args;
996                 sendMessage(H.DUMP_ACTIVITY, data, 0, 0, true /*async*/);
997             } catch (IOException e) {
998                 Slog.w(TAG, "dumpActivity failed", e);
999             }
1000         }
1001
1002         public void dumpProvider(FileDescriptor fd, IBinder providertoken,
1003                 String[] args) {
1004             DumpComponentInfo data = new DumpComponentInfo();
1005             try {
1006                 data.fd = ParcelFileDescriptor.dup(fd);
1007                 data.token = providertoken;
1008                 data.args = args;
1009                 sendMessage(H.DUMP_PROVIDER, data, 0, 0, true /*async*/);
1010             } catch (IOException e) {
1011                 Slog.w(TAG, "dumpProvider failed", e);
1012             }
1013         }
1014
1015         @Override
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);
1021             try {
1022                 dumpMemInfo(pw, mem, checkin, dumpFullInfo, dumpDalvik, dumpSummaryOnly, dumpUnreachable);
1023             } finally {
1024                 pw.flush();
1025             }
1026         }
1027
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;
1033
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();
1052
1053             dumpMemInfoTable(pw, memInfo, checkin, dumpFullInfo, dumpDalvik, dumpSummaryOnly,
1054                     Process.myPid(),
1055                     (mBoundApplication != null) ? mBoundApplication.processName : "unknown",
1056                     nativeMax, nativeAllocated, nativeFree,
1057                     dalvikMax, dalvikAllocated, dalvikFree);
1058
1059             if (checkin) {
1060                 // NOTE: if you change anything significant below, also consider changing
1061                 // ACTIVITY_THREAD_CHECKIN_VERSION.
1062
1063                 // Object counts
1064                 pw.print(viewInstanceCount); pw.print(',');
1065                 pw.print(viewRootInstanceCount); pw.print(',');
1066                 pw.print(appContextInstanceCount); pw.print(',');
1067                 pw.print(activityInstanceCount); pw.print(',');
1068
1069                 pw.print(globalAssetCount); pw.print(',');
1070                 pw.print(globalAssetManagerCount); pw.print(',');
1071                 pw.print(binderLocalObjectCount); pw.print(',');
1072                 pw.print(binderProxyObjectCount); pw.print(',');
1073
1074                 pw.print(binderDeathObjectCount); pw.print(',');
1075                 pw.print(openSslSocketCount); pw.print(',');
1076
1077                 // SQL
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);
1090                 }
1091                 pw.println();
1092
1093                 return;
1094             }
1095
1096             pw.println(" ");
1097             pw.println(" Objects");
1098             printRow(pw, TWO_COUNT_COLUMNS, "Views:", viewInstanceCount, "ViewRootImpl:",
1099                     viewRootInstanceCount);
1100
1101             printRow(pw, TWO_COUNT_COLUMNS, "AppContexts:", appContextInstanceCount,
1102                     "Activities:", activityInstanceCount);
1103
1104             printRow(pw, TWO_COUNT_COLUMNS, "Assets:", globalAssetCount,
1105                     "AssetManagers:", globalAssetManagerCount);
1106
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);
1113
1114             // SQLite mem info
1115             pw.println(" ");
1116             pw.println(" SQL");
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);
1120             pw.println(" ");
1121             int N = stats.dbStats.size();
1122             if (N > 0) {
1123                 pw.println(" DATABASES");
1124                 printRow(pw, "  %8s %8s %14s %14s  %s", "pgsz", "dbsz", "Lookaside(b)", "cache",
1125                         "Dbname");
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);
1133                 }
1134             }
1135
1136             // Asset details.
1137             String assetAlloc = AssetManager.getAssetAllocations();
1138             if (assetAlloc != null) {
1139                 pw.println(" ");
1140                 pw.println(" Asset Allocations");
1141                 pw.print(assetAlloc);
1142             }
1143
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;
1149                 pw.println(" ");
1150                 pw.println(" Unreachable memory");
1151                 pw.print(Debug.getUnreachableMemory(100, showContents));
1152             }
1153         }
1154
1155         @Override
1156         public void dumpGfxInfo(FileDescriptor fd, String[] args) {
1157             dumpGraphicsInfo(fd);
1158             WindowManagerGlobal.getInstance().dumpGfxInfo(fd, args);
1159         }
1160
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);
1165             pw.flush();
1166         }
1167
1168         @Override
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
1173                 // be closing it.
1174                 final ParcelFileDescriptor dup;
1175                 try {
1176                     dup = ParcelFileDescriptor.dup(fd);
1177                 } catch (IOException e) {
1178                     Log.w(TAG, "Could not dup FD " + fd.getInt$());
1179                     return;
1180                 }
1181
1182                 AsyncTask.THREAD_POOL_EXECUTOR.execute(new Runnable() {
1183                     @Override
1184                     public void run() {
1185                         try {
1186                             dumpDatabaseInfo(dup.getFileDescriptor(), args);
1187                         } finally {
1188                             IoUtils.closeQuietly(dup);
1189                         }
1190                     }
1191                 });
1192             } else {
1193                 dumpDatabaseInfo(fd, args);
1194             }
1195         }
1196
1197         @Override
1198         public void unstableProviderDied(IBinder provider) {
1199             sendMessage(H.UNSTABLE_PROVIDER_DIED, provider);
1200         }
1201
1202         @Override
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);
1211         }
1212
1213         public void setCoreSettings(Bundle coreSettings) {
1214             sendMessage(H.SET_CORE_SETTINGS, coreSettings);
1215         }
1216
1217         public void updatePackageCompatibilityInfo(String pkg, CompatibilityInfo info) {
1218             UpdateCompatibilityData ucd = new UpdateCompatibilityData();
1219             ucd.pkg = pkg;
1220             ucd.info = info;
1221             sendMessage(H.UPDATE_PACKAGE_COMPATIBILITY_INFO, ucd);
1222         }
1223
1224         public void scheduleTrimMemory(int level) {
1225             sendMessage(H.TRIM_MEMORY, null, level);
1226         }
1227
1228         public void scheduleTranslucentConversionComplete(IBinder token, boolean drawComplete) {
1229             sendMessage(H.TRANSLUCENT_CONVERSION_COMPLETE, token, drawComplete ? 1 : 0);
1230         }
1231
1232         public void scheduleOnNewActivityOptions(IBinder token, ActivityOptions options) {
1233             sendMessage(H.ON_NEW_ACTIVITY_OPTIONS,
1234                     new Pair<IBinder, ActivityOptions>(token, options));
1235         }
1236
1237         public void setProcessState(int state) {
1238             updateProcessState(state, true);
1239         }
1240
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;
1252                     }
1253                     VMRuntime.getRuntime().updateProcessState(dalvikProcessState);
1254                     if (false) {
1255                         Slog.i(TAG, "******************* PROCESS STATE CHANGED TO: " + processState
1256                                 + (fromIpc ? " (from ipc": ""));
1257                     }
1258                 }
1259             }
1260         }
1261
1262         @Override
1263         public void scheduleInstallProvider(ProviderInfo provider) {
1264             sendMessage(H.INSTALL_PROVIDER, provider);
1265         }
1266
1267         @Override
1268         public final void updateTimePrefs(boolean is24Hour) {
1269             DateFormat.set24HourTimePref(is24Hour);
1270         }
1271
1272         @Override
1273         public void scheduleCancelVisibleBehind(IBinder token) {
1274             sendMessage(H.CANCEL_VISIBLE_BEHIND, token);
1275         }
1276
1277         @Override
1278         public void scheduleBackgroundVisibleBehindChanged(IBinder token, boolean visible) {
1279             sendMessage(H.BACKGROUND_VISIBLE_BEHIND_CHANGED, token, visible ? 1 : 0);
1280         }
1281
1282         @Override
1283         public void scheduleEnterAnimationComplete(IBinder token) {
1284             sendMessage(H.ENTER_ANIMATION_COMPLETE, token);
1285         }
1286
1287         @Override
1288         public void notifyCleartextNetwork(byte[] firstPacket) {
1289             if (StrictMode.vmCleartextNetworkEnabled()) {
1290                 StrictMode.onCleartextNetworkDetected(firstPacket);
1291             }
1292         }
1293
1294         @Override
1295         public void startBinderTracking() {
1296             sendMessage(H.START_BINDER_TRACKING, null);
1297         }
1298
1299         @Override
1300         public void stopBinderTrackingAndDump(FileDescriptor fd) {
1301             try {
1302                 sendMessage(H.STOP_BINDER_TRACKING_AND_DUMP, ParcelFileDescriptor.dup(fd));
1303             } catch (IOException e) {
1304             }
1305         }
1306
1307         @Override
1308         public void scheduleMultiWindowModeChanged(IBinder token, boolean isInMultiWindowMode)
1309                 throws RemoteException {
1310             sendMessage(H.MULTI_WINDOW_MODE_CHANGED, token, isInMultiWindowMode ? 1 : 0);
1311         }
1312
1313         @Override
1314         public void schedulePictureInPictureModeChanged(IBinder token, boolean isInPipMode)
1315                 throws RemoteException {
1316             sendMessage(H.PICTURE_IN_PICTURE_MODE_CHANGED, token, isInPipMode ? 1 : 0);
1317         }
1318
1319         @Override
1320         public void scheduleLocalVoiceInteractionStarted(IBinder token,
1321                 IVoiceInteractor voiceInteractor) throws RemoteException {
1322             SomeArgs args = SomeArgs.obtain();
1323             args.arg1 = token;
1324             args.arg2 = voiceInteractor;
1325             sendMessage(H.LOCAL_VOICE_INTERACTION_STARTED, args);
1326         }
1327     }
1328
1329     private int getLifecycleSeq() {
1330         synchronized (mResourcesManager) {
1331             return mLifecycleSeq++;
1332         }
1333     }
1334
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;
1353
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;
1391
1392         String codeToString(int code) {
1393             if (DEBUG_MESSAGES) {
1394                 switch (code) {
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";
1447                 }
1448             }
1449             return Integer.toString(code);
1450         }
1451         public void handleMessage(Message msg) {
1452             if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
1453             switch (msg.what) {
1454                 case LAUNCH_ACTIVITY: {
1455                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
1456                     final ActivityClientRecord r = (ActivityClientRecord) msg.obj;
1457
1458                     r.packageInfo = getPackageInfoNoCheck(
1459                             r.activityInfo.applicationInfo, r.compatInfo);
1460                     handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");
1461                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1462                 } break;
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);
1468                 } break;
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);
1475                     maybeSnapshot();
1476                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1477                 } break;
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);
1484                 } break;
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);
1490                 } break;
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);
1496                 } break;
1497                 case SHOW_WINDOW:
1498                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityShowWindow");
1499                     handleWindowVisibility((IBinder)msg.obj, true);
1500                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1501                     break;
1502                 case HIDE_WINDOW:
1503                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityHideWindow");
1504                     handleWindowVisibility((IBinder)msg.obj, false);
1505                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1506                     break;
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);
1513                     break;
1514                 case SEND_RESULT:
1515                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityDeliverResult");
1516                     handleSendResult((ResultData)msg.obj);
1517                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1518                     break;
1519                 case DESTROY_ACTIVITY:
1520                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityDestroy");
1521                     handleDestroyActivity((IBinder)msg.obj, msg.arg1 != 0,
1522                             msg.arg2, false);
1523                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1524                     break;
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);
1530                     break;
1531                 case EXIT_APPLICATION:
1532                     if (mInitialApplication != null) {
1533                         mInitialApplication.onTerminate();
1534                     }
1535                     Looper.myLooper().quit();
1536                     break;
1537                 case NEW_INTENT:
1538                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityNewIntent");
1539                     handleNewIntent((NewIntentData)msg.obj);
1540                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1541                     break;
1542                 case RECEIVER:
1543                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "broadcastReceiveComp");
1544                     handleReceiver((ReceiverData)msg.obj);
1545                     maybeSnapshot();
1546                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1547                     break;
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);
1552                     break;
1553                 case BIND_SERVICE:
1554                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceBind");
1555                     handleBindService((BindServiceData)msg.obj);
1556                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1557                     break;
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);
1562                     break;
1563                 case SERVICE_ARGS:
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);
1567                     break;
1568                 case STOP_SERVICE:
1569                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceStop");
1570                     handleStopService((IBinder)msg.obj);
1571                     maybeSnapshot();
1572                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1573                     break;
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);
1579                     break;
1580                 case CLEAN_UP_CONTEXT:
1581                     ContextCleanupInfo cci = (ContextCleanupInfo)msg.obj;
1582                     cci.context.performFinalCleanup(cci.who, cci.what);
1583                     break;
1584                 case GC_WHEN_IDLE:
1585                     scheduleGcIdler();
1586                     break;
1587                 case DUMP_SERVICE:
1588                     handleDumpService((DumpComponentInfo)msg.obj);
1589                     break;
1590                 case LOW_MEMORY:
1591                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "lowMemory");
1592                     handleLowMemory();
1593                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1594                     break;
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);
1600                     break;
1601                 case PROFILER_CONTROL:
1602                     handleProfilerControl(msg.arg1 != 0, (ProfilerInfo)msg.obj, msg.arg2);
1603                     break;
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);
1608                     break;
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);
1613                     break;
1614                 case SUICIDE:
1615                     Process.killProcess(Process.myPid());
1616                     break;
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);
1621                     break;
1622                 case ENABLE_JIT:
1623                     ensureJitEnabled();
1624                     break;
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);
1629                     break;
1630                 case SCHEDULE_CRASH:
1631                     throw new RemoteServiceException((String)msg.obj);
1632                 case DUMP_HEAP:
1633                     handleDumpHeap(msg.arg1 != 0, (DumpHeapData)msg.obj);
1634                     break;
1635                 case DUMP_ACTIVITY:
1636                     handleDumpActivity((DumpComponentInfo)msg.obj);
1637                     break;
1638                 case DUMP_PROVIDER:
1639                     handleDumpProvider((DumpComponentInfo)msg.obj);
1640                     break;
1641                 case SLEEPING:
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);
1645                     break;
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);
1650                     break;
1651                 case UPDATE_PACKAGE_COMPATIBILITY_INFO:
1652                     handleUpdatePackageCompatibilityInfo((UpdateCompatibilityData)msg.obj);
1653                     break;
1654                 case TRIM_MEMORY:
1655                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "trimMemory");
1656                     handleTrimMemory(msg.arg1);
1657                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1658                     break;
1659                 case UNSTABLE_PROVIDER_DIED:
1660                     handleUnstableProviderDied((IBinder)msg.obj, false);
1661                     break;
1662                 case REQUEST_ASSIST_CONTEXT_EXTRAS:
1663                     handleRequestAssistContextExtras((RequestAssistContextExtras)msg.obj);
1664                     break;
1665                 case TRANSLUCENT_CONVERSION_COMPLETE:
1666                     handleTranslucentConversionComplete((IBinder)msg.obj, msg.arg1 == 1);
1667                     break;
1668                 case INSTALL_PROVIDER:
1669                     handleInstallProvider((ProviderInfo) msg.obj);
1670                     break;
1671                 case ON_NEW_ACTIVITY_OPTIONS:
1672                     Pair<IBinder, ActivityOptions> pair = (Pair<IBinder, ActivityOptions>) msg.obj;
1673                     onNewActivityOptions(pair.first, pair.second);
1674                     break;
1675                 case CANCEL_VISIBLE_BEHIND:
1676                     handleCancelVisibleBehind((IBinder) msg.obj);
1677                     break;
1678                 case BACKGROUND_VISIBLE_BEHIND_CHANGED:
1679                     handleOnBackgroundVisibleBehindChanged((IBinder) msg.obj, msg.arg1 > 0);
1680                     break;
1681                 case ENTER_ANIMATION_COMPLETE:
1682                     handleEnterAnimationComplete((IBinder) msg.obj);
1683                     break;
1684                 case START_BINDER_TRACKING:
1685                     handleStartBinderTracking();
1686                     break;
1687                 case STOP_BINDER_TRACKING_AND_DUMP:
1688                     handleStopBinderTrackingAndDump((ParcelFileDescriptor) msg.obj);
1689                     break;
1690                 case MULTI_WINDOW_MODE_CHANGED:
1691                     handleMultiWindowModeChanged((IBinder) msg.obj, msg.arg1 == 1);
1692                     break;
1693                 case PICTURE_IN_PICTURE_MODE_CHANGED:
1694                     handlePictureInPictureModeChanged((IBinder) msg.obj, msg.arg1 == 1);
1695                     break;
1696                 case LOCAL_VOICE_INTERACTION_STARTED:
1697                     handleLocalVoiceInteractionStarted((IBinder) ((SomeArgs) msg.obj).arg1,
1698                             (IVoiceInteractor) ((SomeArgs) msg.obj).arg2);
1699                     break;
1700             }
1701             Object obj = msg.obj;
1702             if (obj instanceof SomeArgs) {
1703                 ((SomeArgs) obj).recycle();
1704             }
1705             if (DEBUG_MESSAGES) Slog.v(TAG, "<<< done: " + codeToString(msg.what));
1706         }
1707
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;
1714                 try {
1715                     Context context = getSystemContext();
1716                     if(context == null) {
1717                         Log.e(TAG, "cannot get a valid context");
1718                         return;
1719                     }
1720                     PackageManager pm = context.getPackageManager();
1721                     if(pm == null) {
1722                         Log.e(TAG, "cannot get a valid PackageManager");
1723                         return;
1724                     }
1725                     packageInfo = pm.getPackageInfo(
1726                             packageName, PackageManager.GET_ACTIVITIES);
1727                 } catch (NameNotFoundException e) {
1728                     Log.e(TAG, "cannot get package info for " + packageName, e);
1729                 }
1730                 SamplingProfilerIntegration.writeSnapshot(mBoundApplication.processName, packageInfo);
1731             }
1732         }
1733     }
1734
1735     private class Idler implements MessageQueue.IdleHandler {
1736         @Override
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;
1743             }
1744             if (a != null) {
1745                 mNewActivities = null;
1746                 IActivityManager am = ActivityManagerNative.getDefault();
1747                 ActivityClientRecord prev;
1748                 do {
1749                     if (localLOGV) Slog.v(
1750                         TAG, "Reporting idle of " + a +
1751                         " finished=" +
1752                         (a.activity != null && a.activity.mFinished));
1753                     if (a.activity != null && !a.activity.mFinished) {
1754                         try {
1755                             am.activityIdle(a.token, a.createdConfig, stopProfiling);
1756                             a.createdConfig = null;
1757                         } catch (RemoteException ex) {
1758                             throw ex.rethrowFromSystemServer();
1759                         }
1760                     }
1761                     prev = a;
1762                     a = a.nextIdle;
1763                     prev.nextIdle = null;
1764                 } while (a != null);
1765             }
1766             if (stopProfiling) {
1767                 mProfiler.stopProfiling();
1768             }
1769             ensureJitEnabled();
1770             return false;
1771         }
1772     }
1773
1774     final class GcIdler implements MessageQueue.IdleHandler {
1775         @Override
1776         public final boolean queueIdle() {
1777             doGcIfNeeded();
1778             return false;
1779         }
1780     }
1781
1782     public static ActivityThread currentActivityThread() {
1783         return sCurrentActivityThread;
1784     }
1785
1786     public static boolean isSystem() {
1787         return (sCurrentActivityThread != null) ? sCurrentActivityThread.mSystemThread : false;
1788     }
1789
1790     public static String currentOpPackageName() {
1791         ActivityThread am = currentActivityThread();
1792         return (am != null && am.getApplication() != null)
1793                 ? am.getApplication().getOpPackageName() : null;
1794     }
1795
1796     public static String currentPackageName() {
1797         ActivityThread am = currentActivityThread();
1798         return (am != null && am.mBoundApplication != null)
1799             ? am.mBoundApplication.appInfo.packageName : null;
1800     }
1801
1802     public static String currentProcessName() {
1803         ActivityThread am = currentActivityThread();
1804         return (am != null && am.mBoundApplication != null)
1805             ? am.mBoundApplication.processName : null;
1806     }
1807
1808     public static Application currentApplication() {
1809         ActivityThread am = currentActivityThread();
1810         return am != null ? am.mInitialApplication : null;
1811     }
1812
1813     public static IPackageManager getPackageManager() {
1814         if (sPackageManager != null) {
1815             //Slog.v("PackageManager", "returning cur default = " + sPackageManager);
1816             return sPackageManager;
1817         }
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;
1823     }
1824
1825     private Configuration mMainThreadConfig = new Configuration();
1826
1827     Configuration applyConfigCompatMainThread(int displayDensity, Configuration config,
1828             CompatibilityInfo compat) {
1829         if (config == null) {
1830             return null;
1831         }
1832         if (!compat.supportsScreen()) {
1833             mMainThreadConfig.setTo(config);
1834             config = mMainThreadConfig;
1835             compat.applyToConfiguration(displayDensity, config);
1836         }
1837         return config;
1838     }
1839
1840     /**
1841      * Creates the top level resources for the given package. Will return an existing
1842      * Resources if one has already been created.
1843      */
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());
1848     }
1849
1850     final Handler getHandler() {
1851         return mH;
1852     }
1853
1854     public final LoadedApk getPackageInfo(String packageName, CompatibilityInfo compatInfo,
1855             int flags) {
1856         return getPackageInfo(packageName, compatInfo, flags, UserHandle.myUserId());
1857     }
1858
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
1866                 ref = null;
1867             } else if ((flags & Context.CONTEXT_INCLUDE_CODE) != 0) {
1868                 ref = mPackages.get(packageName);
1869             } else {
1870                 ref = mResourcePackages.get(packageName);
1871             }
1872
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);
1886                 }
1887                 return packageInfo;
1888             }
1889         }
1890
1891         ApplicationInfo ai = null;
1892         try {
1893             ai = getPackageManager().getApplicationInfo(packageName,
1894                     PackageManager.GET_SHARED_LIBRARY_FILES
1895                             | PackageManager.MATCH_DEBUG_TRIAGED_MISSING,
1896                     userId);
1897         } catch (RemoteException e) {
1898             throw e.rethrowFromSystemServer();
1899         }
1900
1901         if (ai != null) {
1902             return getPackageInfo(ai, compatInfo, flags);
1903         }
1904
1905         return null;
1906     }
1907
1908     public final LoadedApk getPackageInfo(ApplicationInfo ai, CompatibilityInfo compatInfo,
1909             int flags) {
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)
1914                         : true);
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 + ")";
1926                 }
1927                 throw new SecurityException(msg);
1928             }
1929         }
1930         return getPackageInfo(ai, compatInfo, null, securityViolation, includeCode,
1931                 registerPackage);
1932     }
1933
1934     public final LoadedApk getPackageInfoNoCheck(ApplicationInfo ai,
1935             CompatibilityInfo compatInfo) {
1936         return getPackageInfo(ai, compatInfo, null, false, true, false);
1937     }
1938
1939     public final LoadedApk peekPackageInfo(String packageName, boolean includeCode) {
1940         synchronized (mResourcesManager) {
1941             WeakReference<LoadedApk> ref;
1942             if (includeCode) {
1943                 ref = mPackages.get(packageName);
1944             } else {
1945                 ref = mResourcePackages.get(packageName);
1946             }
1947             return ref != null ? ref.get() : null;
1948         }
1949     }
1950
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
1959                 ref = null;
1960             } else if (includeCode) {
1961                 ref = mPackages.get(aInfo.packageName);
1962             } else {
1963                 ref = mResourcePackages.get(aInfo.packageName);
1964             }
1965
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)
1973                         + ")");
1974                 packageInfo =
1975                     new LoadedApk(this, aInfo, compatInfo, baseLoader,
1976                             securityViolation, includeCode &&
1977                             (aInfo.flags&ApplicationInfo.FLAG_HAS_CODE) != 0, registerPackage);
1978
1979                 if (mSystemThread && "android".equals(aInfo.packageName)) {
1980                     packageInfo.installSystemApplicationInfo(aInfo,
1981                             getSystemContext().mPackageInfo.getClassLoader());
1982                 }
1983
1984                 if (differentUser) {
1985                     // Caching not supported across users
1986                 } else if (includeCode) {
1987                     mPackages.put(aInfo.packageName,
1988                             new WeakReference<LoadedApk>(packageInfo));
1989                 } else {
1990                     mResourcePackages.put(aInfo.packageName,
1991                             new WeakReference<LoadedApk>(packageInfo));
1992                 }
1993             }
1994             return packageInfo;
1995         }
1996     }
1997
1998     ActivityThread() {
1999         mResourcesManager = ResourcesManager.getInstance();
2000     }
2001
2002     public ApplicationThread getApplicationThread()
2003     {
2004         return mAppThread;
2005     }
2006
2007     public Instrumentation getInstrumentation()
2008     {
2009         return mInstrumentation;
2010     }
2011
2012     public boolean isProfiling() {
2013         return mProfiler != null && mProfiler.profileFile != null
2014                 && mProfiler.profileFd == null;
2015     }
2016
2017     public String getProfileFilePath() {
2018         return mProfiler.profileFile;
2019     }
2020
2021     public Looper getLooper() {
2022         return mLooper;
2023     }
2024
2025     public Application getApplication() {
2026         return mInitialApplication;
2027     }
2028
2029     public String getProcessName() {
2030         return mBoundApplication.processName;
2031     }
2032
2033     public ContextImpl getSystemContext() {
2034         synchronized (this) {
2035             if (mSystemContext == null) {
2036                 mSystemContext = ContextImpl.createSystemContext(this);
2037             }
2038             return mSystemContext;
2039         }
2040     }
2041
2042     public void installSystemApplicationInfo(ApplicationInfo info, ClassLoader classLoader) {
2043         synchronized (this) {
2044             getSystemContext().installSystemApplicationInfo(info, classLoader);
2045
2046             // give ourselves a default profiler
2047             mProfiler = new Profiler();
2048         }
2049     }
2050
2051     void ensureJitEnabled() {
2052         if (!mJitEnabled) {
2053             mJitEnabled = true;
2054             dalvik.system.VMRuntime.getRuntime().startJitCompilation();
2055         }
2056     }
2057
2058     void scheduleGcIdler() {
2059         if (!mGcIdlerScheduled) {
2060             mGcIdlerScheduled = true;
2061             Looper.myQueue().addIdleHandler(mGcIdler);
2062         }
2063         mH.removeMessages(H.GC_WHEN_IDLE);
2064     }
2065
2066     void unscheduleGcIdler() {
2067         if (mGcIdlerScheduled) {
2068             mGcIdlerScheduled = false;
2069             Looper.myQueue().removeIdleHandler(mGcIdler);
2070         }
2071         mH.removeMessages(H.GC_WHEN_IDLE);
2072     }
2073
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");
2082         }
2083     }
2084
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";
2092
2093     // Formatting for checkin service - update version if row format changes
2094     private static final int ACTIVITY_THREAD_CHECKIN_VERSION = 4;
2095
2096     static void printRow(PrintWriter pw, String format, Object...objs) {
2097         pw.println(String.format(format, objs));
2098     }
2099
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) {
2105
2106         // For checkin, we print one long comma-separated list of values
2107         if (checkin) {
2108             // NOTE: if you change anything significant below, also consider changing
2109             // ACTIVITY_THREAD_CHECKIN_VERSION.
2110
2111             // Header
2112             pw.print(ACTIVITY_THREAD_CHECKIN_VERSION); pw.print(',');
2113             pw.print(pid); pw.print(',');
2114             pw.print(processName); pw.print(',');
2115
2116             // Heap info - max
2117             pw.print(nativeMax); pw.print(',');
2118             pw.print(dalvikMax); pw.print(',');
2119             pw.print("N/A,");
2120             pw.print(nativeMax + dalvikMax); pw.print(',');
2121
2122             // Heap info - allocated
2123             pw.print(nativeAllocated); pw.print(',');
2124             pw.print(dalvikAllocated); pw.print(',');
2125             pw.print("N/A,");
2126             pw.print(nativeAllocated + dalvikAllocated); pw.print(',');
2127
2128             // Heap info - free
2129             pw.print(nativeFree); pw.print(',');
2130             pw.print(dalvikFree); pw.print(',');
2131             pw.print("N/A,");
2132             pw.print(nativeFree + dalvikFree); pw.print(',');
2133
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(',');
2139
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(',');
2145
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(',');
2151
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(',');
2157
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(',');
2163
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(',');
2169
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(',');
2175
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(',');
2182             } else {
2183                 pw.print("N/A,");
2184                 pw.print("N/A,");
2185                 pw.print("N/A,");
2186                 pw.print("N/A,");
2187             }
2188
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(',');
2201                 } else {
2202                     pw.print("N/A,");
2203                 }
2204             }
2205             return;
2206         }
2207
2208         if (!dumpSummaryOnly) {
2209             if (dumpFullInfo) {
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);
2230             } else {
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);
2250             }
2251
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;
2260
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) {
2273                     if (dumpFullInfo) {
2274                         printRow(pw, HEAP_FULL_COLUMN, Debug.MemoryInfo.getOtherLabel(i),
2275                                 myPss, mySwappablePss, mySharedDirty, myPrivateDirty,
2276                                 mySharedClean, myPrivateClean,
2277                                 memInfo.hasSwappedOutPss ? mySwappedOutPss : mySwappedOut,
2278                                 "", "", "");
2279                     } else {
2280                         printRow(pw, HEAP_COLUMN, Debug.MemoryInfo.getOtherLabel(i),
2281                                 myPss, myPrivateDirty,
2282                                 myPrivateClean,
2283                                 memInfo.hasSwappedOutPss ? mySwappedOutPss : mySwappedOut,
2284                                 "", "", "");
2285                     }
2286                     otherPss -= myPss;
2287                     otherSwappablePss -= mySwappablePss;
2288                     otherSharedDirty -= mySharedDirty;
2289                     otherPrivateDirty -= myPrivateDirty;
2290                     otherSharedClean -= mySharedClean;
2291                     otherPrivateClean -= myPrivateClean;
2292                     otherSwappedOut -= mySwappedOut;
2293                     otherSwappedOutPss -= mySwappedOutPss;
2294                 }
2295             }
2296
2297             if (dumpFullInfo) {
2298                 printRow(pw, HEAP_FULL_COLUMN, "Unknown", otherPss, otherSwappablePss,
2299                         otherSharedDirty, otherPrivateDirty, otherSharedClean, otherPrivateClean,
2300                         memInfo.hasSwappedOutPss ? otherSwappedOutPss : otherSwappedOut,
2301                         "", "", "");
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);
2310             } else {
2311                 printRow(pw, HEAP_COLUMN, "Unknown", otherPss,
2312                         otherPrivateDirty, otherPrivateClean,
2313                         memInfo.hasSwappedOutPss ? otherSwappedOutPss : otherSwappedOut,
2314                         "", "", "");
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);
2322             }
2323
2324             if (dumpDalvik) {
2325                 pw.println(" ");
2326                 pw.println(" Dalvik Details");
2327
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) {
2341                         if (dumpFullInfo) {
2342                             printRow(pw, HEAP_FULL_COLUMN, Debug.MemoryInfo.getOtherLabel(i),
2343                                     myPss, mySwappablePss, mySharedDirty, myPrivateDirty,
2344                                     mySharedClean, myPrivateClean,
2345                                     memInfo.hasSwappedOutPss ? mySwappedOutPss : mySwappedOut,
2346                                     "", "", "");
2347                         } else {
2348                             printRow(pw, HEAP_COLUMN, Debug.MemoryInfo.getOtherLabel(i),
2349                                     myPss, myPrivateDirty,
2350                                     myPrivateClean,
2351                                     memInfo.hasSwappedOutPss ? mySwappedOutPss : mySwappedOut,
2352                                     "", "", "");
2353                         }
2354                     }
2355                 }
2356             }
2357         }
2358
2359         pw.println(" ");
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());
2377         pw.println(" ");
2378         if (memInfo.hasSwappedOutPss) {
2379             printRow(pw, TWO_COUNT_COLUMNS,
2380                 "TOTAL:", memInfo.getSummaryTotalPss(),
2381                 "TOTAL SWAP PSS:", memInfo.getSummaryTotalSwapPss());
2382         } else {
2383             printRow(pw, TWO_COUNT_COLUMNS,
2384                 "TOTAL:", memInfo.getSummaryTotalPss(),
2385                 "TOTAL SWAP (KB):", memInfo.getSummaryTotalSwap());
2386         }
2387     }
2388
2389     public void registerOnActivityPausedListener(Activity activity,
2390             OnActivityPausedListener listener) {
2391         synchronized (mOnPauseListeners) {
2392             ArrayList<OnActivityPausedListener> list = mOnPauseListeners.get(activity);
2393             if (list == null) {
2394                 list = new ArrayList<OnActivityPausedListener>();
2395                 mOnPauseListeners.put(activity, list);
2396             }
2397             list.add(listener);
2398         }
2399     }
2400
2401     public void unregisterOnActivityPausedListener(Activity activity,
2402             OnActivityPausedListener listener) {
2403         synchronized (mOnPauseListeners) {
2404             ArrayList<OnActivityPausedListener> list = mOnPauseListeners.get(activity);
2405             if (list != null) {
2406                 list.remove(listener);
2407             }
2408         }
2409     }
2410
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);
2418         }
2419         return aInfo;
2420     }
2421
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();
2426             r.token = token;
2427             r.ident = 0;
2428             r.intent = intent;
2429             r.state = state;
2430             r.parent = parent;
2431             r.embeddedID = id;
2432             r.activityInfo = activityInfo;
2433             r.lastNonConfigurationInstances = lastNonConfigurationInstances;
2434         if (localLOGV) {
2435             ComponentName compname = intent.getComponent();
2436             String name;
2437             if (compname != null) {
2438                 name = compname.toShortString();
2439             } else {
2440                 name = "(Intent " + intent + ").getComponent() returned null";
2441             }
2442             Slog.v(TAG, "Performing launch: action=" + intent.getAction()
2443                     + ", comp=" + name
2444                     + ", token=" + token);
2445         }
2446         return performLaunchActivity(r, null);
2447     }
2448
2449     public final Activity getActivity(IBinder token) {
2450         return mActivities.get(token).activity;
2451     }
2452
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);
2461     }
2462
2463     private void sendMessage(int what, Object obj) {
2464         sendMessage(what, obj, 0, 0, false);
2465     }
2466
2467     private void sendMessage(int what, Object obj, int arg1) {
2468         sendMessage(what, obj, arg1, 0, false);
2469     }
2470
2471     private void sendMessage(int what, Object obj, int arg1, int arg2) {
2472         sendMessage(what, obj, arg1, arg2, false);
2473     }
2474
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();
2480         msg.what = what;
2481         msg.obj = obj;
2482         msg.arg1 = arg1;
2483         msg.arg2 = arg2;
2484         if (async) {
2485             msg.setAsynchronous(true);
2486         }
2487         mH.sendMessage(msg);
2488     }
2489
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 +
2493                         "seq= " + seq);
2494         Message msg = Message.obtain();
2495         msg.what = what;
2496         SomeArgs args = SomeArgs.obtain();
2497         args.arg1 = obj;
2498         args.argi1 = arg1;
2499         args.argi2 = arg2;
2500         args.argi3 = seq;
2501         msg.obj = args;
2502         mH.sendMessage(msg);
2503     }
2504
2505     final void scheduleContextCleanup(ContextImpl context, String who,
2506             String what) {
2507         ContextCleanupInfo cci = new ContextCleanupInfo();
2508         cci.context = context;
2509         cci.who = who;
2510         cci.what = what;
2511         sendMessage(H.CLEAN_UP_CONTEXT, cci);
2512     }
2513
2514     private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
2515         // System.out.println("##### [" + System.currentTimeMillis() + "] ActivityThread.performLaunchActivity(" + r + ")");
2516
2517         ActivityInfo aInfo = r.activityInfo;
2518         if (r.packageInfo == null) {
2519             r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
2520                     Context.CONTEXT_INCLUDE_CODE);
2521         }
2522
2523         ComponentName component = r.intent.getComponent();
2524         if (component == null) {
2525             component = r.intent.resolveActivity(
2526                 mInitialApplication.getPackageManager());
2527             r.intent.setComponent(component);
2528         }
2529
2530         if (r.activityInfo.targetActivity != null) {
2531             component = new ComponentName(r.activityInfo.packageName,
2532                     r.activityInfo.targetActivity);
2533         }
2534
2535         Activity activity = null;
2536         try {
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);
2545             }
2546         } catch (Exception e) {
2547             if (!mInstrumentation.onException(activity, e)) {
2548                 throw new RuntimeException(
2549                     "Unable to instantiate activity " + component
2550                     + ": " + e.toString(), e);
2551             }
2552         }
2553
2554         try {
2555             Application app = r.packageInfo.makeApplication(false, mInstrumentation);
2556
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());
2564
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);
2571                 }
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;
2579                 }
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);
2584
2585                 if (customIntent != null) {
2586                     activity.mIntent = customIntent;
2587                 }
2588                 r.lastNonConfigurationInstances = null;
2589                 activity.mStartedActivity = false;
2590                 int theme = r.activityInfo.getThemeResource();
2591                 if (theme != 0) {
2592                     activity.setTheme(theme);
2593                 }
2594
2595                 activity.mCalled = false;
2596                 if (r.isPersistable()) {
2597                     mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
2598                 } else {
2599                     mInstrumentation.callActivityOnCreate(activity, r.state);
2600                 }
2601                 if (!activity.mCalled) {
2602                     throw new SuperNotCalledException(
2603                         "Activity " + r.intent.getComponent().toShortString() +
2604                         " did not call through to super.onCreate()");
2605                 }
2606                 r.activity = activity;
2607                 r.stopped = true;
2608                 if (!r.activity.mFinished) {
2609                     activity.performStart();
2610                     r.stopped = false;
2611                 }
2612                 if (!r.activity.mFinished) {
2613                     if (r.isPersistable()) {
2614                         if (r.state != null || r.persistentState != null) {
2615                             mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state,
2616                                     r.persistentState);
2617                         }
2618                     } else if (r.state != null) {
2619                         mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
2620                     }
2621                 }
2622                 if (!r.activity.mFinished) {
2623                     activity.mCalled = false;
2624                     if (r.isPersistable()) {
2625                         mInstrumentation.callActivityOnPostCreate(activity, r.state,
2626                                 r.persistentState);
2627                     } else {
2628                         mInstrumentation.callActivityOnPostCreate(activity, r.state);
2629                     }
2630                     if (!activity.mCalled) {
2631                         throw new SuperNotCalledException(
2632                             "Activity " + r.intent.getComponent().toShortString() +
2633                             " did not call through to super.onPostCreate()");
2634                     }
2635                 }
2636             }
2637             r.paused = true;
2638
2639             mActivities.put(r.token, r);
2640
2641         } catch (SuperNotCalledException e) {
2642             throw e;
2643
2644         } catch (Exception e) {
2645             if (!mInstrumentation.onException(activity, e)) {
2646                 throw new RuntimeException(
2647                     "Unable to start activity " + component
2648                     + ": " + e.toString(), e);
2649             }
2650         }
2651
2652         return activity;
2653     }
2654
2655     private Context createBaseContextForActivity(ActivityClientRecord r, final Activity activity) {
2656         int displayId = Display.DEFAULT_DISPLAY;
2657         try {
2658             displayId = ActivityManagerNative.getDefault().getActivityDisplayId(r.token);
2659         } catch (RemoteException e) {
2660             throw e.rethrowFromSystemServer();
2661         }
2662
2663         ContextImpl appContext = ContextImpl.createActivityContext(
2664                 this, r.packageInfo, r.token, displayId, r.overrideConfig);
2665         appContext.setOuterContext(activity);
2666         Context baseContext = appContext;
2667
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) {
2677                     Display display =
2678                             dm.getCompatibleDisplay(id, appContext.getDisplayAdjustments(id));
2679                     baseContext = appContext.createDisplayContext(display);
2680                     break;
2681                 }
2682             }
2683         }
2684         return baseContext;
2685     }
2686
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;
2692
2693         if (r.profilerInfo != null) {
2694             mProfiler.setProfiler(r.profilerInfo);
2695             mProfiler.startProfiling();
2696         }
2697
2698         // Make sure we are running with the most recent config.
2699         handleConfigurationChanged(null, null);
2700
2701         if (localLOGV) Slog.v(
2702             TAG, "Handling launch of " + r);
2703
2704         // Initialize before creating the activity
2705         WindowManagerGlobal.initialize();
2706
2707         Activity a = performLaunchActivity(r, customIntent);
2708
2709         if (a != null) {
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);
2715
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
2723                 // state it has.
2724                 performPauseActivityIfNeeded(r, reason);
2725
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()) {
2732                     r.state = oldState;
2733                 }
2734             }
2735         } else {
2736             // If there was an error, for any reason, tell the activity manager to stop us.
2737             try {
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();
2743             }
2744         }
2745     }
2746
2747     private void reportSizeConfigurations(ActivityClientRecord r) {
2748         Configuration[] configurations = r.activity.getResources().getSizeConfigurations();
2749         if (configurations == null) {
2750             return;
2751         }
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);
2759             }
2760             if (config.screenWidthDp != Configuration.SCREEN_WIDTH_DP_UNDEFINED) {
2761                 horizontal.put(config.screenWidthDp, 0);
2762             }
2763             if (config.smallestScreenWidthDp != Configuration.SMALLEST_SCREEN_WIDTH_DP_UNDEFINED) {
2764                 smallest.put(config.smallestScreenWidthDp, 0);
2765             }
2766         }
2767         try {
2768             ActivityManagerNative.getDefault().reportSizeConfigurations(r.token,
2769                     horizontal.copyKeys(), vertical.copyKeys(), smallest.copyKeys());
2770         } catch (RemoteException ex) {
2771             throw ex.rethrowFromSystemServer();
2772         }
2773
2774     }
2775
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);
2784         }
2785     }
2786
2787     public final void performNewIntents(IBinder token, List<ReferrerIntent> intents) {
2788         ActivityClientRecord r = mActivities.get(token);
2789         if (r != null) {
2790             final boolean resumed = !r.paused;
2791             if (resumed) {
2792                 r.activity.mTemporaryPause = true;
2793                 mInstrumentation.callActivityOnPause(r.activity);
2794             }
2795             deliverNewIntents(r, intents);
2796             if (resumed) {
2797                 r.activity.performResume();
2798                 r.activity.mTemporaryPause = false;
2799             }
2800         }
2801     }
2802
2803     private void handleNewIntent(NewIntentData data) {
2804         performNewIntents(data.token, data.intents);
2805     }
2806
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();
2815                 }
2816                 mLastAssistStructures.remove(i);
2817             }
2818         }
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;
2824         if (r != 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);
2839                 } else {
2840                     content.setDefaultIntent(new Intent());
2841                 }
2842                 r.activity.onProvideAssistContent(content);
2843             }
2844         }
2845         if (structure == null) {
2846             structure = new AssistStructure();
2847         }
2848         mLastAssistStructures.add(new WeakReference<>(structure));
2849         IActivityManager mgr = ActivityManagerNative.getDefault();
2850         try {
2851             mgr.reportAssistContextExtras(cmd.requestToken, data, structure, content, referrer);
2852         } catch (RemoteException e) {
2853             throw e.rethrowFromSystemServer();
2854         }
2855     }
2856
2857     public void handleTranslucentConversionComplete(IBinder token, boolean drawComplete) {
2858         ActivityClientRecord r = mActivities.get(token);
2859         if (r != null) {
2860             r.activity.onTranslucentConversionComplete(drawComplete);
2861         }
2862     }
2863
2864     public void onNewActivityOptions(IBinder token, ActivityOptions options) {
2865         ActivityClientRecord r = mActivities.get(token);
2866         if (r != null) {
2867             r.activity.onNewActivityOptions(options);
2868         }
2869     }
2870
2871     public void handleCancelVisibleBehind(IBinder token) {
2872         ActivityClientRecord r = mActivities.get(token);
2873         if (r != null) {
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()");
2883                 }
2884                 activity.mVisibleBehind = false;
2885             }
2886         }
2887         try {
2888             ActivityManagerNative.getDefault().backgroundResourcesReleased(token);
2889         } catch (RemoteException e) {
2890             throw e.rethrowFromSystemServer();
2891         }
2892     }
2893
2894     public void handleOnBackgroundVisibleBehindChanged(IBinder token, boolean visible) {
2895         ActivityClientRecord r = mActivities.get(token);
2896         if (r != null) {
2897             r.activity.onBackgroundVisibleBehindChanged(visible);
2898         }
2899     }
2900
2901     public void handleInstallProvider(ProviderInfo info) {
2902         final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
2903         try {
2904             installContentProviders(mInitialApplication, Lists.newArrayList(info));
2905         } finally {
2906             StrictMode.setThreadPolicy(oldPolicy);
2907         }
2908     }
2909
2910     private void handleEnterAnimationComplete(IBinder token) {
2911         ActivityClientRecord r = mActivities.get(token);
2912         if (r != null) {
2913             r.activity.dispatchEnterAnimationComplete();
2914         }
2915     }
2916
2917     private void handleStartBinderTracking() {
2918         Binder.enableTracing();
2919     }
2920
2921     private void handleStopBinderTrackingAndDump(ParcelFileDescriptor fd) {
2922         try {
2923             Binder.disableTracing();
2924             Binder.getTransactionTracker().writeTracesToFile(fd);
2925         } finally {
2926             IoUtils.closeQuietly(fd);
2927             Binder.getTransactionTracker().clearTraces();
2928         }
2929     }
2930
2931     private void handleMultiWindowModeChanged(IBinder token, boolean isInMultiWindowMode) {
2932         final ActivityClientRecord r = mActivities.get(token);
2933         if (r != null) {
2934             r.activity.dispatchMultiWindowModeChanged(isInMultiWindowMode);
2935         }
2936     }
2937
2938     private void handlePictureInPictureModeChanged(IBinder token, boolean isInPipMode) {
2939         final ActivityClientRecord r = mActivities.get(token);
2940         if (r != null) {
2941             r.activity.dispatchPictureInPictureModeChanged(isInPipMode);
2942         }
2943     }
2944
2945     private void handleLocalVoiceInteractionStarted(IBinder token, IVoiceInteractor interactor) {
2946         final ActivityClientRecord r = mActivities.get(token);
2947         if (r != null) {
2948             r.voiceInteractor = interactor;
2949             r.activity.setVoiceInteractor(interactor);
2950             if (interactor == null) {
2951                 r.activity.onLocalVoiceInteractionStopped();
2952             } else {
2953                 r.activity.onLocalVoiceInteractionStarted();
2954             }
2955         }
2956     }
2957
2958     private static final ThreadLocal<Intent> sCurrentBroadcastIntent = new ThreadLocal<Intent>();
2959
2960     /**
2961      * Return the Intent that's currently being handled by a
2962      * BroadcastReceiver on this thread, or null if none.
2963      * @hide
2964      */
2965     public static Intent getIntentBeingBroadcast() {
2966         return sCurrentBroadcastIntent.get();
2967     }
2968
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();
2973
2974         String component = data.intent.getComponent().getClassName();
2975
2976         LoadedApk packageInfo = getPackageInfoNoCheck(
2977                 data.info.applicationInfo, data.compatInfo);
2978
2979         IActivityManager mgr = ActivityManagerNative.getDefault();
2980
2981         BroadcastReceiver receiver;
2982         try {
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);
2995         }
2996
2997         try {
2998             Application app = packageInfo.makeApplication(false, mInstrumentation);
2999
3000             if (localLOGV) Slog.v(
3001                 TAG, "Performing receive of " + data.intent
3002                 + ": app=" + app
3003                 + ", appName=" + app.getPackageName()
3004                 + ", pkg=" + packageInfo.getPackageName()
3005                 + ", comp=" + data.intent.getComponent().toShortString()
3006                 + ", dir=" + packageInfo.getAppDir());
3007
3008             ContextImpl context = (ContextImpl)app.getBaseContext();
3009             sCurrentBroadcastIntent.set(data.intent);
3010             receiver.setPendingResult(data);
3011             receiver.onReceive(context.getReceiverRestrictedContext(),
3012                     data.intent);
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);
3021             }
3022         } finally {
3023             sCurrentBroadcastIntent.set(null);
3024         }
3025
3026         if (receiver.getPendingResult() != null) {
3027             data.finish();
3028         }
3029     }
3030
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);
3034
3035         // Sanity check the requested target package's uid against ours
3036         try {
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);
3042                 return;
3043             }
3044         } catch (RemoteException e) {
3045             throw e.rethrowFromSystemServer();
3046         }
3047
3048         // no longer idle; we have backup work to do
3049         unscheduleGcIdler();
3050
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");
3056             return;
3057         }
3058
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";
3064         }
3065
3066         try {
3067             IBinder binder = null;
3068             BackupAgent agent = mBackupAgents.get(packageName);
3069             if (agent != null) {
3070                 // reusing the existing instance
3071                 if (DEBUG_BACKUP) {
3072                     Slog.v(TAG, "Reusing existing agent instance");
3073                 }
3074                 binder = agent.onBind();
3075             } else {
3076                 try {
3077                     if (DEBUG_BACKUP) Slog.v(TAG, "Initializing agent class " + classname);
3078
3079                     java.lang.ClassLoader cl = packageInfo.getClassLoader();
3080                     agent = (BackupAgent) cl.loadClass(classname).newInstance();
3081
3082                     // set up the agent's context
3083                     ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
3084                     context.setOuterContext(agent);
3085                     agent.attach(context);
3086
3087                     agent.onCreate();
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) {
3096                         throw e;
3097                     }
3098                     // falling through with 'binder' still null
3099                 }
3100             }
3101
3102             // tell the OS that we're live now
3103             try {
3104                 ActivityManagerNative.getDefault().backupAgentCreated(packageName, binder);
3105             } catch (RemoteException e) {
3106                 throw e.rethrowFromSystemServer();
3107             }
3108         } catch (Exception e) {
3109             throw new RuntimeException("Unable to create BackupAgent "
3110                     + classname + ": " + e.toString(), e);
3111         }
3112     }
3113
3114     // Tear down a BackupAgent
3115     private void handleDestroyBackupAgent(CreateBackupAgentData data) {
3116         if (DEBUG_BACKUP) Slog.v(TAG, "handleDestroyBackupAgent: " + data);
3117
3118         LoadedApk packageInfo = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
3119         String packageName = packageInfo.mPackageName;
3120         BackupAgent agent = mBackupAgents.get(packageName);
3121         if (agent != null) {
3122             try {
3123                 agent.onDestroy();
3124             } catch (Exception e) {
3125                 Slog.w(TAG, "Exception thrown in onDestroy by backup agent of " + data.appInfo);
3126                 e.printStackTrace();
3127             }
3128             mBackupAgents.remove(packageName);
3129         } else {
3130             Slog.w(TAG, "Attempt to destroy unknown backup agent " + data);
3131         }
3132     }
3133
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();
3138
3139         LoadedApk packageInfo = getPackageInfoNoCheck(
3140                 data.info.applicationInfo, data.compatInfo);
3141         Service service = null;
3142         try {
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);
3150             }
3151         }
3152
3153         try {
3154             if (localLOGV) Slog.v(TAG, "Creating service " + data.info.name);
3155
3156             ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
3157             context.setOuterContext(service);
3158
3159             Application app = packageInfo.makeApplication(false, mInstrumentation);
3160             service.attach(context, this, data.info.name, data.token, app,
3161                     ActivityManagerNative.getDefault());
3162             service.onCreate();
3163             mServices.put(data.token, service);
3164             try {
3165                 ActivityManagerNative.getDefault().serviceDoneExecuting(
3166                         data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
3167             } catch (RemoteException e) {
3168                 throw e.rethrowFromSystemServer();
3169             }
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);
3175             }
3176         }
3177     }
3178
3179     private void handleBindService(BindServiceData data) {
3180         Service s = mServices.get(data.token);
3181         if (DEBUG_SERVICE)
3182             Slog.v(TAG, "handleBindService s=" + s + " rebind=" + data.rebind);
3183         if (s != null) {
3184             try {
3185                 data.intent.setExtrasClassLoader(s.getClassLoader());
3186                 data.intent.prepareToEnterProcess();
3187                 try {
3188                     if (!data.rebind) {
3189                         IBinder binder = s.onBind(data.intent);
3190                         ActivityManagerNative.getDefault().publishService(
3191                                 data.token, data.intent, binder);
3192                     } else {
3193                         s.onRebind(data.intent);
3194                         ActivityManagerNative.getDefault().serviceDoneExecuting(
3195                                 data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
3196                     }
3197                     ensureJitEnabled();
3198                 } catch (RemoteException ex) {
3199                     throw ex.rethrowFromSystemServer();
3200                 }
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);
3206                 }
3207             }
3208         }
3209     }
3210
3211     private void handleUnbindService(BindServiceData data) {
3212         Service s = mServices.get(data.token);
3213         if (s != null) {
3214             try {
3215                 data.intent.setExtrasClassLoader(s.getClassLoader());
3216                 data.intent.prepareToEnterProcess();
3217                 boolean doRebind = s.onUnbind(data.intent);
3218                 try {
3219                     if (doRebind) {
3220                         ActivityManagerNative.getDefault().unbindFinished(
3221                                 data.token, data.intent, doRebind);
3222                     } else {
3223                         ActivityManagerNative.getDefault().serviceDoneExecuting(
3224                                 data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
3225                     }
3226                 } catch (RemoteException ex) {
3227                     throw ex.rethrowFromSystemServer();
3228                 }
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);
3234                 }
3235             }
3236         }
3237     }
3238
3239     private void handleDumpService(DumpComponentInfo info) {
3240         final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
3241         try {
3242             Service s = mServices.get(info.token);
3243             if (s != null) {
3244                 PrintWriter pw = new FastPrintWriter(new FileOutputStream(
3245                         info.fd.getFileDescriptor()));
3246                 s.dump(info.fd.getFileDescriptor(), pw, info.args);
3247                 pw.flush();
3248             }
3249         } finally {
3250             IoUtils.closeQuietly(info.fd);
3251             StrictMode.setThreadPolicy(oldPolicy);
3252         }
3253     }
3254
3255     private void handleDumpActivity(DumpComponentInfo info) {
3256         final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
3257         try {
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);
3263                 pw.flush();
3264             }
3265         } finally {
3266             IoUtils.closeQuietly(info.fd);
3267             StrictMode.setThreadPolicy(oldPolicy);
3268         }
3269     }
3270
3271     private void handleDumpProvider(DumpComponentInfo info) {
3272         final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
3273         try {
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);
3279                 pw.flush();
3280             }
3281         } finally {
3282             IoUtils.closeQuietly(info.fd);
3283             StrictMode.setThreadPolicy(oldPolicy);
3284         }
3285     }
3286
3287     private void handleServiceArgs(ServiceArgsData data) {
3288         Service s = mServices.get(data.token);
3289         if (s != null) {
3290             try {
3291                 if (data.args != null) {
3292                     data.args.setExtrasClassLoader(s.getClassLoader());
3293                     data.args.prepareToEnterProcess();
3294                 }
3295                 int res;
3296                 if (!data.taskRemoved) {
3297                     res = s.onStartCommand(data.args, data.flags, data.startId);
3298                 } else {
3299                     s.onTaskRemoved(data.args);
3300                     res = Service.START_TASK_REMOVED_COMPLETE;
3301                 }
3302
3303                 QueuedWork.waitToFinish();
3304
3305                 try {
3306                     ActivityManagerNative.getDefault().serviceDoneExecuting(
3307                             data.token, SERVICE_DONE_EXECUTING_START, data.startId, res);
3308                 } catch (RemoteException e) {
3309                     throw e.rethrowFromSystemServer();
3310                 }
3311                 ensureJitEnabled();
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);
3317                 }
3318             }
3319         }
3320     }
3321
3322     private void handleStopService(IBinder token) {
3323         Service s = mServices.remove(token);
3324         if (s != null) {
3325             try {
3326                 if (localLOGV) Slog.v(TAG, "Destroying service " + s);
3327                 s.onDestroy();
3328                 Context context = s.getBaseContext();
3329                 if (context instanceof ContextImpl) {
3330                     final String who = s.getClassName();
3331                     ((ContextImpl) context).scheduleFinalCleanup(who, "Service");
3332                 }
3333
3334                 QueuedWork.waitToFinish();
3335
3336                 try {
3337                     ActivityManagerNative.getDefault().serviceDoneExecuting(
3338                             token, SERVICE_DONE_EXECUTING_STOP, 0, 0);
3339                 } catch (RemoteException e) {
3340                     throw e.rethrowFromSystemServer();
3341                 }
3342             } catch (Exception e) {
3343                 if (!mInstrumentation.onException(s, e)) {
3344                     throw new RuntimeException(
3345                             "Unable to stop service " + s
3346                             + ": " + e.toString(), e);
3347                 }
3348                 Slog.i(TAG, "handleStopService: exception for " + token, e);
3349             }
3350         } else {
3351             Slog.i(TAG, "handleStopService: token=" + token + " not found.");
3352         }
3353         //Slog.i(TAG, "Running services: " + mServices);
3354     }
3355
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) {
3362             if (clearHide) {
3363                 r.hideForNow = false;
3364                 r.activity.mStartedActivity = false;
3365             }
3366             try {
3367                 r.activity.onStateNotSaved();
3368                 r.activity.mFragments.noteStateNotSaved();
3369                 if (r.pendingIntents != null) {
3370                     deliverNewIntents(r, r.pendingIntents);
3371                     r.pendingIntents = null;
3372                 }
3373                 if (r.pendingResults != null) {
3374                     deliverResults(r, r.pendingResults);
3375                     r.pendingResults = null;
3376                 }
3377                 r.activity.performResume();
3378
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;
3388                     }
3389                 }
3390
3391                 EventLog.writeEvent(LOG_AM_ON_RESUME_CALLED, UserHandle.myUserId(),
3392                         r.activity.getComponentName().getClassName(), reason);
3393
3394                 r.paused = false;
3395                 r.stopped = false;
3396                 r.state = null;
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);
3404                 }
3405             }
3406         }
3407         return r;
3408     }
3409
3410     static final void cleanUpPendingRemoveWindows(ActivityClientRecord r, boolean force) {
3411         if (r.mPreserveWindow && !force) {
3412             return;
3413         }
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");
3421             }
3422         }
3423         r.mPendingRemoveWindow = null;
3424         r.mPendingRemoveWindowManager = null;
3425     }
3426
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")) {
3431             return;
3432         }
3433
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;
3438
3439         // TODO Push resumeArgs into the activity for consideration
3440         r = performResumeActivity(token, clearHide, reason);
3441
3442         if (r != null) {
3443             final Activity a = r.activity;
3444
3445             if (localLOGV) Slog.v(
3446                 TAG, "Resume " + r + " started activity: " +
3447                 a.mStartedActivity + ", hideForNow: " + r.hideForNow
3448                 + ", finished: " + a.mFinished);
3449
3450             final int forwardBit = isForward ?
3451                     WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION : 0;
3452
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) {
3458                 try {
3459                     willBeVisible = ActivityManagerNative.getDefault().willActivityBeVisible(
3460                             a.getActivityToken());
3461                 } catch (RemoteException e) {
3462                     throw e.rethrowFromSystemServer();
3463                 }
3464             }
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();
3471                 a.mDecor = decor;
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();
3482                     if (impl != null) {
3483                         impl.notifyChildRebuilt();
3484                     }
3485                 }
3486                 if (a.mVisibleFromClient && !a.mWindowAdded) {
3487                     a.mWindowAdded = true;
3488                     wm.addView(decor, l);
3489                 }
3490
3491             // If the window has already been added, but during resume
3492             // we started another activity, then don't yet make the
3493             // window visible.
3494             } else if (!willBeVisible) {
3495                 if (localLOGV) Slog.v(
3496                     TAG, "Launch " + r + " mStartedActivity set");
3497                 r.hideForNow = true;
3498             }
3499
3500             // Get rid of anything left hanging around.
3501             cleanUpPendingRemoveWindows(r, false /* force */);
3502
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);
3511                     r.newConfig = null;
3512                 }
3513                 if (localLOGV) Slog.v(TAG, "Resuming " + r + " with isForward="
3514                         + isForward);
3515                 WindowManager.LayoutParams l = r.window.getAttributes();
3516                 if ((l.softInputMode
3517                         & WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION)
3518                         != forwardBit) {
3519                     l.softInputMode = (l.softInputMode
3520                             & (~WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION))
3521                             | forwardBit;
3522                     if (r.activity.mVisibleFromClient) {
3523                         ViewManager wm = a.getWindowManager();
3524                         View decor = r.window.getDecorView();
3525                         wm.updateViewLayout(decor, l);
3526                     }
3527                 }
3528                 r.activity.mVisibleFromServer = true;
3529                 mNumVisibleActivities++;
3530                 if (r.activity.mVisibleFromClient) {
3531                     r.activity.makeVisible();
3532                 }
3533             }
3534
3535             if (!r.onlyLocalRequest) {
3536                 r.nextIdle = mNewActivities;
3537                 mNewActivities = r;
3538                 if (localLOGV) Slog.v(
3539                     TAG, "Scheduling idle handler for " + r);
3540                 Looper.myQueue().addIdleHandler(new Idler());
3541             }
3542             r.onlyLocalRequest = false;
3543
3544             // Tell the activity manager we have resumed.
3545             if (reallyResume) {
3546                 try {
3547                     ActivityManagerNative.getDefault().activityResumed(token);
3548                 } catch (RemoteException ex) {
3549                     throw ex.rethrowFromSystemServer();
3550                 }
3551             }
3552
3553         } else {
3554             // If an exception was thrown when trying to resume, then
3555             // just end this activity.
3556             try {
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();
3562             }
3563         }
3564     }
3565
3566     private int mThumbnailWidth = -1;
3567     private int mThumbnailHeight = -1;
3568     private Bitmap mAvailThumbnailBitmap = null;
3569     private Canvas mThumbnailCanvas = null;
3570
3571     private Bitmap createThumbnailBitmap(ActivityClientRecord r) {
3572         Bitmap thumbnail = mAvailThumbnailBitmap;
3573         try {
3574             if (thumbnail == null) {
3575                 int w = mThumbnailWidth;
3576                 int h;
3577                 if (w < 0) {
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);
3583                 } else {
3584                     h = mThumbnailHeight;
3585                 }
3586
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);
3592                 }
3593             }
3594
3595             if (thumbnail != null) {
3596                 Canvas cv = mThumbnailCanvas;
3597                 if (cv == null) {
3598                     mThumbnailCanvas = cv = new Canvas();
3599                 }
3600
3601                 cv.setBitmap(thumbnail);
3602                 if (!r.activity.onCreateThumbnail(thumbnail, cv)) {
3603                     mAvailThumbnailBitmap = thumbnail;
3604                     thumbnail = null;
3605                 }
3606                 cv.setBitmap(null);
3607             }
3608
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);
3615             }
3616             thumbnail = null;
3617         }
3618
3619         return thumbnail;
3620     }
3621
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")) {
3627             return;
3628         }
3629         if (r != null) {
3630             //Slog.v(TAG, "userLeaving=" + userLeaving + " handling pause of " + r);
3631             if (userLeaving) {
3632                 performUserLeavingActivity(r);
3633             }
3634
3635             r.activity.mConfigChangeFlags |= configChanges;
3636             performPauseActivity(token, finished, r.isPreHoneycomb(), "handlePauseActivity");
3637
3638             // Make sure any pending writes are now committed.
3639             if (r.isPreHoneycomb()) {
3640                 QueuedWork.waitToFinish();
3641             }
3642
3643             // Tell the activity manager we have paused.
3644             if (!dontReport) {
3645                 try {
3646                     ActivityManagerNative.getDefault().activityPaused(token);
3647                 } catch (RemoteException ex) {
3648                     throw ex.rethrowFromSystemServer();
3649                 }
3650             }
3651             mSomeActivitiesChanged = true;
3652         }
3653     }
3654
3655     final void performUserLeavingActivity(ActivityClientRecord r) {
3656         mInstrumentation.callActivityOnUserLeaving(r.activity);
3657     }
3658
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;
3663     }
3664
3665     final Bundle performPauseActivity(ActivityClientRecord r, boolean finished,
3666             boolean saveState, String reason) {
3667         if (r.paused) {
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
3671                 // isn't resumed.
3672                 return null;
3673             }
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);
3678         }
3679         if (finished) {
3680             r.activity.mFinished = true;
3681         }
3682
3683         // Next have the activity save its current state and managed dialogs...
3684         if (!r.activity.mFinished && saveState) {
3685             callCallActivityOnSaveInstanceState(r);
3686         }
3687
3688         performPauseActivityIfNeeded(r, reason);
3689
3690         // Notify any outstanding on paused listeners
3691         ArrayList<OnActivityPausedListener> listeners;
3692         synchronized (mOnPauseListeners) {
3693             listeners = mOnPauseListeners.remove(r.activity);
3694         }
3695         int size = (listeners != null ? listeners.size() : 0);
3696         for (int i = 0; i < size; i++) {
3697             listeners.get(i).onPaused(r.activity);
3698         }
3699
3700         return !r.activity.mFinished && saveState ? r.state : null;
3701     }
3702
3703     private void performPauseActivityIfNeeded(ActivityClientRecord r, String reason) {
3704         if (r.paused) {
3705             // You are already paused silly...
3706             return;
3707         }
3708
3709         try {
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()");
3717             }
3718         } catch (SuperNotCalledException e) {
3719             throw 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);
3724             }
3725         }
3726         r.paused = true;
3727     }
3728
3729     final void performStopActivity(IBinder token, boolean saveState, String reason) {
3730         ActivityClientRecord r = mActivities.get(token);
3731         performStopActivityInner(r, null, false, saveState, reason);
3732     }
3733
3734     private static class StopInfo implements Runnable {
3735         ActivityClientRecord activity;
3736         Bundle state;
3737         PersistableBundle persistentState;
3738         CharSequence description;
3739
3740         @Override public void run() {
3741             // Tell activity manager we have been stopped.
3742             try {
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);
3750                     return;
3751                 }
3752                 throw ex.rethrowFromSystemServer();
3753             }
3754         }
3755     }
3756
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;
3762
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
3767         // here.
3768         public boolean removePending;
3769
3770         ProviderRefCount(IActivityManager.ContentProviderHolder inHolder,
3771                 ProviderClientRecord inClient, int sCount, int uCount) {
3772             holder = inHolder;
3773             client = inClient;
3774             stableCount = sCount;
3775             unstableCount = uCount;
3776         }
3777     }
3778
3779     /**
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.
3786      */
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);
3790         if (r != null) {
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.
3796                     return;
3797                 }
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());
3803             }
3804
3805             // One must first be paused before stopped...
3806             performPauseActivityIfNeeded(r, reason);
3807
3808             if (info != null) {
3809                 try {
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);
3820                     }
3821                 }
3822             }
3823
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);
3828                 }
3829             }
3830
3831             if (!keepShown) {
3832                 try {
3833                     // Now we are idle.
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);
3841                     }
3842                 }
3843                 r.stopped = true;
3844                 EventLog.writeEvent(LOG_AM_ON_STOP_CALLED, UserHandle.myUserId(),
3845                         r.activity.getComponentName().getClassName(), reason);
3846             }
3847         }
3848     }
3849
3850     private void updateVisibility(ActivityClientRecord r, boolean show) {
3851         View v = r.activity.mDecor;
3852         if (v != null) {
3853             if (show) {
3854                 if (!r.activity.mVisibleFromServer) {
3855                     r.activity.mVisibleFromServer = true;
3856                     mNumVisibleActivities++;
3857                     if (r.activity.mVisibleFromClient) {
3858                         r.activity.makeVisible();
3859                     }
3860                 }
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);
3866                     r.newConfig = null;
3867                 }
3868             } else {
3869                 if (r.activity.mVisibleFromServer) {
3870                     r.activity.mVisibleFromServer = false;
3871                     mNumVisibleActivities--;
3872                     v.setVisibility(View.INVISIBLE);
3873                 }
3874             }
3875         }
3876     }
3877
3878     private void handleStopActivity(IBinder token, boolean show, int configChanges, int seq) {
3879         ActivityClientRecord r = mActivities.get(token);
3880         if (!checkAndUpdateLifecycleSeq(seq, r, "stopActivity")) {
3881             return;
3882         }
3883         r.activity.mConfigChangeFlags |= configChanges;
3884
3885         StopInfo info = new StopInfo();
3886         performStopActivityInner(r, info, show, true, "handleStopActivity");
3887
3888         if (localLOGV) Slog.v(
3889             TAG, "Finishing stop of " + r + ": show=" + show
3890             + " win=" + r.window);
3891
3892         updateVisibility(r, show);
3893
3894         // Make sure any pending writes are now committed.
3895         if (!r.isPreHoneycomb()) {
3896             QueuedWork.waitToFinish();
3897         }
3898
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.
3904         info.activity = r;
3905         info.state = r.state;
3906         info.persistentState = r.persistentState;
3907         mH.post(info);
3908         mSomeActivitiesChanged = true;
3909     }
3910
3911     private static boolean checkAndUpdateLifecycleSeq(int seq, ActivityClientRecord r,
3912             String action) {
3913         if (r == null) {
3914             return true;
3915         }
3916         if (seq < r.lastProcessedSeq) {
3917             if (DEBUG_ORDER) Slog.d(TAG, action + " for " + r + " ignored, because seq=" + seq
3918                     + " < mCurrentLifecycleSeq=" + r.lastProcessedSeq);
3919             return false;
3920         }
3921         r.lastProcessedSeq = seq;
3922         return true;
3923     }
3924
3925     final void performRestartActivity(IBinder token) {
3926         ActivityClientRecord r = mActivities.get(token);
3927         if (r.stopped) {
3928             r.activity.performRestart();
3929             r.stopped = false;
3930         }
3931     }
3932
3933     private void handleWindowVisibility(IBinder token, boolean show) {
3934         ActivityClientRecord r = mActivities.get(token);
3935
3936         if (r == null) {
3937             Log.w(TAG, "handleWindowVisibility: no activity for token " + token);
3938             return;
3939         }
3940
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();
3947
3948             r.activity.performRestart();
3949             r.stopped = false;
3950         }
3951         if (r.activity.mDecor != null) {
3952             if (false) Slog.v(
3953                 TAG, "Handle window " + r + " visibility: " + show);
3954             updateVisibility(r, show);
3955         }
3956         mSomeActivitiesChanged = true;
3957     }
3958
3959     private void handleSleeping(IBinder token, boolean sleeping) {
3960         ActivityClientRecord r = mActivities.get(token);
3961
3962         if (r == null) {
3963             Log.w(TAG, "handleSleeping: no activity for token " + token);
3964             return;
3965         }
3966
3967         if (sleeping) {
3968             if (!r.stopped && !r.isPreHoneycomb()) {
3969                 try {
3970                     // Now we are idle.
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);
3978                     }
3979                 }
3980                 r.stopped = true;
3981                 EventLog.writeEvent(LOG_AM_ON_STOP_CALLED, UserHandle.myUserId(),
3982                         r.activity.getComponentName().getClassName(), "sleeping");
3983             }
3984
3985             // Make sure any pending writes are now committed.
3986             if (!r.isPreHoneycomb()) {
3987                 QueuedWork.waitToFinish();
3988             }
3989
3990             // Tell activity manager we slept.
3991             try {
3992                 ActivityManagerNative.getDefault().activitySlept(r.token);
3993             } catch (RemoteException ex) {
3994                 throw ex.rethrowFromSystemServer();
3995             }
3996         } else {
3997             if (r.stopped && r.activity.mVisibleFromServer) {
3998                 r.activity.performRestart();
3999                 r.stopped = false;
4000             }
4001         }
4002     }
4003
4004     private void handleSetCoreSettings(Bundle coreSettings) {
4005         synchronized (mResourcesManager) {
4006             mCoreSettings = coreSettings;
4007         }
4008         onCoreSettingsChange();
4009     }
4010
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;
4016
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 */);
4021             }
4022         }
4023     }
4024
4025     private void handleUpdatePackageCompatibilityInfo(UpdateCompatibilityData data) {
4026         LoadedApk apk = peekPackageInfo(data.pkg, false);
4027         if (apk != null) {
4028             apk.setCompatibilityInfo(data.info);
4029         }
4030         apk = peekPackageInfo(data.pkg, true);
4031         if (apk != null) {
4032             apk.setCompatibilityInfo(data.info);
4033         }
4034         handleConfigurationChanged(mConfiguration, data.info);
4035         WindowManagerGlobal.getInstance().reportNewConfiguration(mConfiguration);
4036     }
4037
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);
4042             try {
4043                 if (ri.mData != null) {
4044                     ri.mData.setExtrasClassLoader(r.activity.getClassLoader());
4045                     ri.mData.prepareToEnterProcess();
4046                 }
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);
4057                 }
4058             }
4059         }
4060     }
4061
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);
4065         if (r != null) {
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);
4073             }
4074             if (resumed) {
4075                 try {
4076                     // Now we are idle.
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()");
4084                     }
4085                 } catch (SuperNotCalledException e) {
4086                     throw 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);
4093                     }
4094                 }
4095             }
4096             deliverResults(r, res.results);
4097             if (resumed) {
4098                 r.activity.performResume();
4099                 r.activity.mTemporaryPause = false;
4100             }
4101         }
4102     }
4103
4104     public final ActivityClientRecord performDestroyActivity(IBinder token, boolean finishing) {
4105         return performDestroyActivity(token, finishing, 0, false);
4106     }
4107
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);
4113         if (r != null) {
4114             activityClass = r.activity.getClass();
4115             r.activity.mConfigChangeFlags |= configChanges;
4116             if (finishing) {
4117                 r.activity.mFinished = true;
4118             }
4119
4120             performPauseActivityIfNeeded(r, "destroy");
4121
4122             if (!r.stopped) {
4123                 try {
4124                     r.activity.performStop(r.mPreserveWindow);
4125                 } catch (SuperNotCalledException e) {
4126                     throw 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);
4133                     }
4134                 }
4135                 r.stopped = true;
4136                 EventLog.writeEvent(LOG_AM_ON_STOP_CALLED, UserHandle.myUserId(),
4137                         r.activity.getComponentName().getClassName(), "destroy");
4138             }
4139             if (getNonConfigInstance) {
4140                 try {
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);
4149                     }
4150                 }
4151             }
4152             try {
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()");
4159                 }
4160                 if (r.window != null) {
4161                     r.window.closeAllPanels();
4162                 }
4163             } catch (SuperNotCalledException e) {
4164                 throw 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);
4170                 }
4171             }
4172         }
4173         mActivities.remove(token);
4174         StrictMode.decrementExpectedActivityCount(activityClass);
4175         return r;
4176     }
4177
4178     private static String safeToComponentShortString(Intent intent) {
4179         ComponentName component = intent.getComponent();
4180         return component == null ? "[Unknown]" : component.toShortString();
4181     }
4182
4183     private void handleDestroyActivity(IBinder token, boolean finishing,
4184             int configChanges, boolean getNonConfigInstance) {
4185         ActivityClientRecord r = performDestroyActivity(token, finishing,
4186                 configChanges, getNonConfigInstance);
4187         if (r != null) {
4188             cleanUpPendingRemoveWindows(r, finishing);
4189             WindowManager wm = r.activity.getWindowManager();
4190             View v = r.activity.mDecor;
4191             if (v != null) {
4192                 if (r.activity.mVisibleFromServer) {
4193                     mNumVisibleActivities--;
4194                 }
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();
4206                     } else {
4207                         wm.removeViewImmediate(v);
4208                     }
4209                 }
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");
4220                 }
4221                 r.activity.mDecor = null;
4222             }
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");
4232             }
4233
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
4237             // cleanly.
4238             Context c = r.activity.getBaseContext();
4239             if (c instanceof ContextImpl) {
4240                 ((ContextImpl) c).scheduleFinalCleanup(
4241                         r.activity.getClass().getName(), "Activity");
4242             }
4243         }
4244         if (finishing) {
4245             try {
4246                 ActivityManagerNative.getDefault().activityDestroyed(token);
4247             } catch (RemoteException ex) {
4248                 throw ex.rethrowFromSystemServer();
4249             }
4250         }
4251         mSomeActivitiesChanged = true;
4252     }
4253
4254     /**
4255      * @param preserveWindow Whether the activity should try to reuse the window it created,
4256      *                        including the decor view after the relaunch.
4257      */
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;
4263
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) {
4269                     target = r;
4270                     if (pendingResults != null) {
4271                         if (r.pendingResults != null) {
4272                             r.pendingResults.addAll(pendingResults);
4273                         } else {
4274                             r.pendingResults = pendingResults;
4275                         }
4276                     }
4277                     if (pendingNewIntents != null) {
4278                         if (r.pendingIntents != null) {
4279                             r.pendingIntents.addAll(pendingNewIntents);
4280                         } else {
4281                             r.pendingIntents = pendingNewIntents;
4282                         }
4283                     }
4284
4285                     // For each relaunch request, activity manager expects an answer
4286                     if (!r.onlyLocalRequest && fromServer) {
4287                         try {
4288                             ActivityManagerNative.getDefault().activityRelaunched(token);
4289                         } catch (RemoteException e) {
4290                             throw e.rethrowFromSystemServer();
4291                         }
4292                     }
4293                     break;
4294                 }
4295             }
4296
4297             if (target == null) {
4298                 if (DEBUG_ORDER) Slog.d(TAG, "requestRelaunchActivity: target is null, fromServer:"
4299                         + fromServer);
4300                 target = new ActivityClientRecord();
4301                 target.token = token;
4302                 target.pendingResults = pendingResults;
4303                 target.pendingIntents = pendingNewIntents;
4304                 target.mPreserveWindow = preserveWindow;
4305                 if (!fromServer) {
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;
4313                     }
4314                     target.onlyLocalRequest = true;
4315                 }
4316                 mRelaunchingActivities.add(target);
4317                 sendMessage(H.RELAUNCH_ACTIVITY, target);
4318             }
4319
4320             if (fromServer) {
4321                 target.startsNotResumed = notResumed;
4322                 target.onlyLocalRequest = false;
4323             }
4324             if (config != null) {
4325                 target.createdConfig = config;
4326             }
4327             if (overrideConfig != null) {
4328                 target.overrideConfig = overrideConfig;
4329             }
4330             target.pendingConfigChanges |= configChanges;
4331             target.relaunchSeq = getLifecycleSeq();
4332         }
4333         if (DEBUG_ORDER) Slog.d(TAG, "relaunchActivity " + ActivityThread.this + ", target "
4334                 + target + " operation received seq: " + target.relaunchSeq);
4335     }
4336
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;
4342
4343         Configuration changedConfig = null;
4344         int configChanges = 0;
4345
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;
4352             tmp = null;
4353             for (int i=0; i<N; i++) {
4354                 ActivityClientRecord r = mRelaunchingActivities.get(i);
4355                 if (r.token == token) {
4356                     tmp = r;
4357                     configChanges |= tmp.pendingConfigChanges;
4358                     mRelaunchingActivities.remove(i);
4359                     i--;
4360                     N--;
4361                 }
4362             }
4363
4364             if (tmp == null) {
4365                 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Abort, activity not relaunching!");
4366                 return;
4367             }
4368
4369             if (DEBUG_CONFIGURATION) Slog.v(TAG, "Relaunching activity "
4370                     + tmp.token + " with configChanges=0x"
4371                     + Integer.toHexString(configChanges));
4372
4373             if (mPendingConfiguration != null) {
4374                 changedConfig = mPendingConfiguration;
4375                 mPendingConfiguration = null;
4376             }
4377         }
4378
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);
4382         } else {
4383             tmp.lastProcessedSeq = tmp.relaunchSeq;
4384         }
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;
4395                 }
4396             }
4397         }
4398
4399         if (DEBUG_CONFIGURATION) Slog.v(TAG, "Relaunching activity "
4400                 + tmp.token + ": changedConfig=" + changedConfig);
4401
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);
4407         }
4408
4409         ActivityClientRecord r = mActivities.get(tmp.token);
4410         if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handling relaunch of " + r);
4411         if (r == null) {
4412             if (!tmp.onlyLocalRequest) {
4413                 try {
4414                     ActivityManagerNative.getDefault().activityRelaunched(tmp.token);
4415                 } catch (RemoteException e) {
4416                     throw e.rethrowFromSystemServer();
4417                 }
4418             }
4419             return;
4420         }
4421
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;
4428
4429         r.activity.mChangingConfigurations = true;
4430
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.
4437         //
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
4441         // everything
4442         try {
4443             if (r.mPreserveWindow || r.onlyLocalRequest) {
4444                 WindowManagerGlobal.getWindowSession().prepareToReplaceWindows(
4445                         r.token, !r.onlyLocalRequest);
4446             }
4447         } catch (RemoteException e) {
4448             throw e.rethrowFromSystemServer();
4449         }
4450
4451         // Need to ensure state is saved.
4452         if (!r.paused) {
4453             performPauseActivity(r.token, false, r.isPreHoneycomb(), "handleRelaunchActivity");
4454         }
4455         if (r.state == null && !r.stopped && !r.isPreHoneycomb()) {
4456             callCallActivityOnSaveInstanceState(r);
4457         }
4458
4459         handleDestroyActivity(r.token, false, configChanges, true);
4460
4461         r.activity = null;
4462         r.window = null;
4463         r.hideForNow = false;
4464         r.nextIdle = null;
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;
4469             } else {
4470                 r.pendingResults.addAll(tmp.pendingResults);
4471             }
4472         }
4473         if (tmp.pendingIntents != null) {
4474             if (r.pendingIntents == null) {
4475                 r.pendingIntents = tmp.pendingIntents;
4476             } else {
4477                 r.pendingIntents.addAll(tmp.pendingIntents);
4478             }
4479         }
4480         r.startsNotResumed = tmp.startsNotResumed;
4481         r.overrideConfig = tmp.overrideConfig;
4482
4483         handleLaunchActivity(r, currentIntent, "handleRelaunchActivity");
4484
4485         if (!tmp.onlyLocalRequest) {
4486             try {
4487                 ActivityManagerNative.getDefault().activityRelaunched(r.token);
4488                 if (r.window != null) {
4489                     r.window.reportActivityRelaunched();
4490                 }
4491             } catch (RemoteException e) {
4492                 throw e.rethrowFromSystemServer();
4493             }
4494         }
4495     }
4496
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,
4503                     r.persistentState);
4504         } else {
4505             mInstrumentation.callActivityOnSaveInstanceState(r.activity, r.state);
4506         }
4507     }
4508
4509     ArrayList<ComponentCallbacks2> collectComponentCallbacks(
4510             boolean allActivities, Configuration newConfig) {
4511         ArrayList<ComponentCallbacks2> callbacks
4512                 = new ArrayList<ComponentCallbacks2>();
4513
4514         synchronized (mResourcesManager) {
4515             final int NAPP = mAllApplications.size();
4516             for (int i=0; i<NAPP; i++) {
4517                 callbacks.add(mAllApplications.get(i));
4518             }
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;
4523                 if (a != null) {
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.
4530                         callbacks.add(a);
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
4536                         // configuration.
4537                         if (DEBUG_CONFIGURATION) {
4538                             Slog.v(TAG, "Setting activity "
4539                                     + ar.activityInfo.name + " newConfig=" + thisConfig);
4540                         }
4541                         ar.newConfig = thisConfig;
4542                     }
4543                 }
4544             }
4545             final int NSVC = mServices.size();
4546             for (int i=0; i<NSVC; i++) {
4547                 callbacks.add(mServices.valueAt(i));
4548             }
4549         }
4550         synchronized (mProviderMap) {
4551             final int NPRV = mLocalProviders.size();
4552             for (int i=0; i<NPRV; i++) {
4553                 callbacks.add(mLocalProviders.valueAt(i).mLocalProvider);
4554             }
4555         }
4556
4557         return callbacks;
4558     }
4559
4560     /**
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.
4569      */
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);
4576         }
4577         performConfigurationChanged(r.activity, r.token, r.tmpConfig, r.overrideConfig,
4578                 reportToActivity);
4579         freeTextLayoutCachesIfNeeded(r.activity.mCurrentConfig.diff(r.tmpConfig));
4580     }
4581
4582     /**
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.
4587      */
4588     private static Configuration createNewConfigAndUpdateIfNotNull(@NonNull Configuration base,
4589             @Nullable Configuration override) {
4590         if (override == null) {
4591             return base;
4592         }
4593         Configuration newConfig = new Configuration(base);
4594         newConfig.updateFrom(override);
4595         return newConfig;
4596     }
4597
4598     /**
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.
4609      */
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;
4621         }
4622
4623         boolean shouldChangeConfig = false;
4624         if ((activity == null) || (activity.mCurrentConfig == null)) {
4625             shouldChangeConfig = true;
4626         } else {
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);
4631             if (diff != 0) {
4632                 shouldChangeConfig = true;
4633             }
4634         }
4635
4636         if (shouldChangeConfig) {
4637             // Propagate the configuration change to the Activity and ResourcesManager.
4638
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();
4645             }
4646
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);
4658             }
4659
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);
4667             }
4668
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()");
4674                 }
4675                 activity.mConfigChangeFlags = 0;
4676                 activity.mCurrentConfig = new Configuration(newConfig);
4677             }
4678         }
4679     }
4680
4681     public final void applyConfigurationToResources(Configuration config) {
4682         synchronized (mResourcesManager) {
4683             mResourcesManager.applyConfigurationToResourcesLocked(config, null);
4684         }
4685     }
4686
4687     final Configuration applyCompatConfiguration(int displayDensity) {
4688         Configuration config = mConfiguration;
4689         if (mCompatConfiguration == null) {
4690             mCompatConfiguration = new Configuration();
4691         }
4692         mCompatConfiguration.setTo(mConfiguration);
4693         if (mResourcesManager.applyCompatConfigurationLocked(displayDensity,
4694                 mCompatConfiguration)) {
4695             config = mCompatConfiguration;
4696         }
4697         return config;
4698     }
4699
4700     final void handleConfigurationChanged(Configuration config, CompatibilityInfo compat) {
4701
4702         int configDiff = 0;
4703
4704         synchronized (mResourcesManager) {
4705             if (mPendingConfiguration != null) {
4706                 if (!mPendingConfiguration.isOtherSeqNewer(config)) {
4707                     config = mPendingConfiguration;
4708                     mCurDefaultDisplayDpi = config.densityDpi;
4709                     updateDefaultDensity();
4710                 }
4711                 mPendingConfiguration = null;
4712             }
4713
4714             if (config == null) {
4715                 return;
4716             }
4717
4718             if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handle configuration changed: "
4719                     + config);
4720
4721             mResourcesManager.applyConfigurationToResourcesLocked(config, compat);
4722             updateLocaleListFromAppContext(mInitialApplication.getApplicationContext(),
4723                     mResourcesManager.getConfiguration().getLocales());
4724
4725             if (mConfiguration == null) {
4726                 mConfiguration = new Configuration();
4727             }
4728             if (!mConfiguration.isOtherSeqNewer(config) && compat == null) {
4729                 return;
4730             }
4731
4732             configDiff = mConfiguration.updateFrom(config);
4733             config = applyCompatConfiguration(mCurDefaultDisplayDpi);
4734
4735             final Theme systemTheme = getSystemContext().getTheme();
4736             if ((systemTheme.getChangingConfigurations() & configDiff) != 0) {
4737                 systemTheme.rebase();
4738             }
4739         }
4740
4741         ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(false, config);
4742
4743         freeTextLayoutCachesIfNeeded(configDiff);
4744
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);
4755                 } else {
4756                     performConfigurationChanged(cb, null, config, null, REPORT_TO_ACTIVITY);
4757                 }
4758             }
4759         }
4760     }
4761
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");
4769             }
4770         }
4771     }
4772
4773     final void handleActivityConfigurationChanged(ActivityConfigChangeData data,
4774             boolean reportToActivity) {
4775         ActivityClientRecord r = mActivities.get(data.activityToken);
4776         if (r == null || r.activity == null) {
4777             return;
4778         }
4779
4780         if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handle activity config changed: "
4781                 + r.activityInfo.name + ", with callback=" + reportToActivity);
4782
4783         r.overrideConfig = data.overrideConfig;
4784         performConfigurationChangedForActivity(r, mCompatConfiguration, reportToActivity);
4785         mSomeActivitiesChanged = true;
4786     }
4787
4788     final void handleProfilerControl(boolean start, ProfilerInfo profilerInfo, int profileType) {
4789         if (start) {
4790             try {
4791                 switch (profileType) {
4792                     default:
4793                         mProfiler.setProfiler(profilerInfo);
4794                         mProfiler.startProfiling();
4795                         break;
4796                 }
4797             } catch (RuntimeException e) {
4798                 Slog.w(TAG, "Profiling failed on path " + profilerInfo.profileFile
4799                         + " -- can the process access this path?");
4800             } finally {
4801                 try {
4802                     profilerInfo.profileFd.close();
4803                 } catch (IOException e) {
4804                     Slog.w(TAG, "Failure closing profile fd", e);
4805                 }
4806             }
4807         } else {
4808             switch (profileType) {
4809                 default:
4810                     mProfiler.stopProfiling();
4811                     break;
4812             }
4813         }
4814     }
4815
4816     /**
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.
4819      *
4820      * @hide
4821      */
4822     public void stopProfiling() {
4823         mProfiler.stopProfiling();
4824     }
4825
4826     static final void handleDumpHeap(boolean managed, DumpHeapData dhd) {
4827         if (managed) {
4828             try {
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?");
4833             } finally {
4834                 try {
4835                     dhd.fd.close();
4836                 } catch (IOException e) {
4837                     Slog.w(TAG, "Failure closing profile fd", e);
4838                 }
4839             }
4840         } else {
4841             Debug.dumpNativeHeap(dhd.fd.getFileDescriptor());
4842         }
4843         try {
4844             ActivityManagerNative.getDefault().dumpHeapFinished(dhd.path);
4845         } catch (RemoteException e) {
4846             throw e.rethrowFromSystemServer();
4847         }
4848     }
4849
4850     final void handleDispatchPackageBroadcast(int cmd, String[] packages) {
4851         boolean hasPkgInfo = false;
4852         switch (cmd) {
4853             case IApplicationThread.PACKAGE_REMOVED:
4854             case IApplicationThread.PACKAGE_REMOVED_DONT_KILL:
4855             {
4856                 final boolean killApp = cmd == IApplicationThread.PACKAGE_REMOVED;
4857                 if (packages == null) {
4858                     break;
4859                 }
4860                 synchronized (mResourcesManager) {
4861                     for (int i = packages.length - 1; i >= 0; i--) {
4862                         if (!hasPkgInfo) {
4863                             WeakReference<LoadedApk> ref = mPackages.get(packages[i]);
4864                             if (ref != null && ref.get() != null) {
4865                                 hasPkgInfo = true;
4866                             } else {
4867                                 ref = mResourcePackages.get(packages[i]);
4868                                 if (ref != null && ref.get() != null) {
4869                                     hasPkgInfo = true;
4870                                 }
4871                             }
4872                         }
4873                         if (killApp) {
4874                             mPackages.remove(packages[i]);
4875                             mResourcePackages.remove(packages[i]);
4876                         }
4877                     }
4878                 }
4879                 break;
4880             }
4881             case IApplicationThread.PACKAGE_REPLACED:
4882             {
4883                 if (packages == null) {
4884                     break;
4885                 }
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) {
4891                             hasPkgInfo = true;
4892                         } else {
4893                             ref = mResourcePackages.get(packages[i]);
4894                             pkgInfo = ref != null ? ref.get() : null;
4895                             if (pkgInfo != null) {
4896                                 hasPkgInfo = true;
4897                             }
4898                         }
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
4902                         // resources.
4903                         if (pkgInfo != null) {
4904                             try {
4905                                 final String packageName = packages[i];
4906                                 final ApplicationInfo aInfo =
4907                                         sPackageManager.getApplicationInfo(
4908                                                 packageName,
4909                                                 0 /*flags*/,
4910                                                 UserHandle.myUserId());
4911
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;
4918                                         }
4919                                     }
4920                                 }
4921                                 final List<String> oldPaths =
4922                                         sPackageManager.getPreviousCodePaths(packageName);
4923                                 pkgInfo.updateApplicationInfo(aInfo, oldPaths);
4924                             } catch (RemoteException e) {
4925                             }
4926                         }
4927                     }
4928                 }
4929                 break;
4930             }
4931         }
4932         ApplicationPackageManager.handlePackageBroadcast(cmd, packages, hasPkgInfo);
4933     }
4934
4935     final void handleLowMemory() {
4936         ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(true, null);
4937
4938         final int N = callbacks.size();
4939         for (int i=0; i<N; i++) {
4940             callbacks.get(i).onLowMemory();
4941         }
4942
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);
4947         }
4948
4949         // Ask graphics to free up as much as possible (font/image caches)
4950         Canvas.freeCaches();
4951
4952         // Ask text layout engine to free also as much as possible
4953         Canvas.freeTextLayoutCaches();
4954
4955         BinderInternal.forceGc("mem");
4956     }
4957
4958     final void handleTrimMemory(int level) {
4959         if (DEBUG_MEMORY_TRIM) Slog.v(TAG, "Trimming memory to level: " + level);
4960
4961         ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(true, null);
4962
4963         final int N = callbacks.size();
4964         for (int i = 0; i < N; i++) {
4965             callbacks.get(i).onTrimMemory(level);
4966         }
4967
4968         WindowManagerGlobal.getInstance().trimMemory(level);
4969     }
4970
4971     private void setupGraphicsSupport(LoadedApk info, File cacheDir) {
4972         if (Process.isIsolated()) {
4973             // Isolated processes aren't going to do UI.
4974             return;
4975         }
4976         Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "setupGraphicsSupport");
4977         try {
4978             int uid = Process.myUid();
4979             String[] packages = getPackageManager().getPackagesForUid(uid);
4980
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);
4986             }
4987         } catch (RemoteException e) {
4988             throw e.rethrowFromSystemServer();
4989         } finally {
4990             Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
4991         }
4992     }
4993
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);
5001         }
5002     }
5003
5004     /**
5005      * Returns the correct library directory for the current ABI.
5006      * <p>
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.
5010      */
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;
5020
5021             final String runtimeIsa = VMRuntime.getRuntime().vmInstructionSet();
5022             if (runtimeIsa.equals(secondaryIsa)) {
5023                 return insInfo.secondaryNativeLibraryDir;
5024             }
5025         }
5026         return insInfo.nativeLibraryDir;
5027     }
5028
5029     /**
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.
5033      */
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);
5040                 return;
5041             }
5042         }
5043
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));
5048     }
5049
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);
5055         }
5056
5057         // Note when this process has started.
5058         Process.setStartTimes(SystemClock.elapsedRealtime(), SystemClock.uptimeMillis());
5059
5060         mBoundApplication = data;
5061         mConfiguration = new Configuration(data.config);
5062         mCompatConfiguration = new Configuration(data.config);
5063
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;
5070         }
5071
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());
5076
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);
5083             }
5084         }
5085
5086         if (mProfiler.profileFd != null) {
5087             mProfiler.startProfiling();
5088         }
5089
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);
5096         }
5097
5098         Message.updateCheckRecycle(data.appInfo.targetSdkVersion);
5099
5100         /*
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
5104          * system time zone.
5105          */
5106         TimeZone.setDefault(null);
5107
5108         /*
5109          * Set the LocaleList. This may change once we create the App Context.
5110          */
5111         LocaleList.setDefault(data.config.getLocales());
5112
5113         synchronized (mResourcesManager) {
5114             /*
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
5118              */
5119             mResourcesManager.applyConfigurationToResourcesLocked(data.config, data.compatInfo);
5120             mCurDefaultDisplayDpi = data.config.densityDpi;
5121
5122             // This calls mResourcesManager so keep it within the synchronized block.
5123             applyCompatConfiguration(mCurDefaultDisplayDpi);
5124         }
5125
5126         data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
5127
5128         /**
5129          * Switch this process to density compatibility mode if needed.
5130          */
5131         if ((data.appInfo.flags&ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES)
5132                 == 0) {
5133             mDensityCompatMode = true;
5134             Bitmap.setDefaultDensity(DisplayMetrics.DENSITY_DEFAULT);
5135         }
5136         updateDefaultDensity();
5137
5138         final boolean is24Hr = "24".equals(mCoreSettings.getString(Settings.System.TIME_12_24));
5139         DateFormat.set24HourTimePref(is24Hr);
5140
5141         View.mDebugViewAttributes =
5142                 mCoreSettings.getInt(Settings.Global.DEBUG_VIEW_ATTRIBUTES, 0) != 0;
5143
5144         /**
5145          * For system applications on userdebug/eng builds, log stack
5146          * traces of disk and network access to dropbox for analysis.
5147          */
5148         if ((data.appInfo.flags &
5149              (ApplicationInfo.FLAG_SYSTEM |
5150               ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0) {
5151             StrictMode.conditionallyEnableDebugLogging();
5152         }
5153
5154         /**
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}.
5158          */
5159         if (data.appInfo.targetSdkVersion >= Build.VERSION_CODES.HONEYCOMB) {
5160             StrictMode.enableDeathOnNetwork();
5161         }
5162
5163         /**
5164          * For apps targetting N or later, we don't allow file:// Uri exposure.
5165          * This is what ultimately throws {@link FileUriExposedException}.
5166          */
5167         if (data.appInfo.targetSdkVersion >= Build.VERSION_CODES.N) {
5168             StrictMode.enableDeathOnFileUriExposure();
5169         }
5170
5171         NetworkSecurityPolicy.getInstance().setCleartextTrafficPermitted(
5172                 (data.appInfo.flags & ApplicationInfo.FLAG_USES_CLEARTEXT_TRAFFIC) != 0);
5173
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...");
5180
5181                 IActivityManager mgr = ActivityManagerNative.getDefault();
5182                 try {
5183                     mgr.showWaitingForDebugger(mAppThread, true);
5184                 } catch (RemoteException ex) {
5185                     throw ex.rethrowFromSystemServer();
5186                 }
5187
5188                 Debug.waitForDebugger();
5189
5190                 try {
5191                     mgr.showWaitingForDebugger(mAppThread, false);
5192                 } catch (RemoteException ex) {
5193                     throw ex.rethrowFromSystemServer();
5194                 }
5195
5196             } else {
5197                 Slog.w(TAG, "Application " + data.info.getPackageName()
5198                       + " can be debugged on port 8100...");
5199             }
5200         }
5201
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();
5207         }
5208
5209         /**
5210          * Initialize the default http proxy in this process for the reasons we set the time zone.
5211          */
5212         Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Setup proxies");
5213         final IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE);
5214         if (b != null) {
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);
5219             try {
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();
5225             }
5226         }
5227         Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
5228
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) {
5233             try {
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);
5239             }
5240
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();
5248         } else {
5249             ii = null;
5250         }
5251
5252         final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);
5253         updateLocaleListFromAppContext(appContext,
5254                 mResourcesManager.getConfiguration().getLocales());
5255
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());
5264             } else {
5265                 Log.v(TAG, "Unable to initialize \"java.io.tmpdir\" property "
5266                         + "due to missing cache directory");
5267             }
5268
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);
5274             } else {
5275                 Log.e(TAG, "Unable to setupGraphicsSupport due to missing code-cache directory");
5276             }
5277         }
5278
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);
5285
5286         // Continue loading instrumentation.
5287         if (ii != null) {
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);
5294
5295             try {
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);
5303             }
5304
5305             final ComponentName component = new ComponentName(ii.packageName, ii.name);
5306             mInstrumentation.init(this, instrContext, appContext, component,
5307                     data.instrumentationWatcher, data.instrumentationUiAutomationConnection);
5308
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);
5315             }
5316         } else {
5317             mInstrumentation = new Instrumentation();
5318         }
5319
5320         if ((data.appInfo.flags&ApplicationInfo.FLAG_LARGE_HEAP) != 0) {
5321             dalvik.system.VMRuntime.getRuntime().clearGrowthLimit();
5322         } else {
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();
5326         }
5327
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();
5332         try {
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;
5337
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);
5346                 }
5347             }
5348
5349             // Do this after providers, since instrumentation tests generally start their
5350             // test thread at this point, and we don't want that racing.
5351             try {
5352                 mInstrumentation.onCreate(data.instrumentationArgs);
5353             }
5354             catch (Exception e) {
5355                 throw new RuntimeException(
5356                     "Exception thrown in onCreate() of "
5357                     + data.instrumentationName + ": " + e.toString(), e);
5358             }
5359
5360             try {
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);
5367                 }
5368             }
5369         } finally {
5370             StrictMode.setThreadPolicy(savedPolicy);
5371         }
5372     }
5373
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();
5379         }
5380         //Slog.i(TAG, "am: " + ActivityManagerNative.getDefault()
5381         //      + ", app thr: " + mAppThread);
5382         try {
5383             am.finishInstrumentation(mAppThread, resultCode, results);
5384         } catch (RemoteException ex) {
5385             throw ex.rethrowFromSystemServer();
5386         }
5387     }
5388
5389     private void installContentProviders(
5390             Context context, List<ProviderInfo> providers) {
5391         final ArrayList<IActivityManager.ContentProviderHolder> results =
5392             new ArrayList<IActivityManager.ContentProviderHolder>();
5393
5394         for (ProviderInfo cpi : providers) {
5395             if (DEBUG_PROVIDER) {
5396                 StringBuilder buf = new StringBuilder(128);
5397                 buf.append("Pub ");
5398                 buf.append(cpi.authority);
5399                 buf.append(": ");
5400                 buf.append(cpi.name);
5401                 Log.i(TAG, buf.toString());
5402             }
5403             IActivityManager.ContentProviderHolder cph = installProvider(context, null, cpi,
5404                     false /*noisy*/, true /*noReleaseNeeded*/, true /*stable*/);
5405             if (cph != null) {
5406                 cph.noReleaseNeeded = true;
5407                 results.add(cph);
5408             }
5409         }
5410
5411         try {
5412             ActivityManagerNative.getDefault().publishContentProviders(
5413                 getApplicationThread(), results);
5414         } catch (RemoteException ex) {
5415             throw ex.rethrowFromSystemServer();
5416         }
5417     }
5418
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) {
5423             return provider;
5424         }
5425
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;
5433         try {
5434             holder = ActivityManagerNative.getDefault().getContentProvider(
5435                     getApplicationThread(), auth, userId, stable);
5436         } catch (RemoteException ex) {
5437             throw ex.rethrowFromSystemServer();
5438         }
5439         if (holder == null) {
5440             Slog.e(TAG, "Failed to find provider info for " + auth);
5441             return null;
5442         }
5443
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;
5449     }
5450
5451     private final void incProviderRefLocked(ProviderRefCount prc, boolean stable) {
5452         if (stable) {
5453             prc.stableCount += 1;
5454             if (prc.stableCount == 1) {
5455                 // We are acquiring a new stable reference on the provider.
5456                 int unstableDelta;
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.
5461                     unstableDelta = -1;
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");
5466                     }
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);
5471                 } else {
5472                     unstableDelta = 0;
5473                 }
5474                 try {
5475                     if (DEBUG_PROVIDER) {
5476                         Slog.v(TAG, "incProviderRef Now stable - "
5477                                 + prc.holder.info.name + ": unstableDelta="
5478                                 + unstableDelta);
5479                     }
5480                     ActivityManagerNative.getDefault().refContentProvider(
5481                             prc.holder.connection, 1, unstableDelta);
5482                 } catch (RemoteException e) {
5483                     //do nothing content provider object is dead any way
5484                 }
5485             }
5486         } else {
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");
5498                     }
5499                     prc.removePending = false;
5500                     mH.removeMessages(H.REMOVE_PROVIDER, prc);
5501                 } else {
5502                     // First unstable ref, increment our count in the
5503                     // activity manager.
5504                     try {
5505                         if (DEBUG_PROVIDER) {
5506                             Slog.v(TAG, "incProviderRef: Now unstable - "
5507                                     + prc.holder.info.name);
5508                         }
5509                         ActivityManagerNative.getDefault().refContentProvider(
5510                                 prc.holder.connection, 0, 1);
5511                     } catch (RemoteException e) {
5512                         //do nothing content provider object is dead any way
5513                     }
5514                 }
5515             }
5516         }
5517     }
5518
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);
5524             if (pr == null) {
5525                 return null;
5526             }
5527
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
5532                 // use this one.
5533                 Log.i(TAG, "Acquiring provider " + auth + " for user " + userId
5534                         + ": existing object's process dead");
5535                 handleUnstableProviderDiedLocked(jBinder, true);
5536                 return null;
5537             }
5538
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);
5542             if (prc != null) {
5543                 incProviderRefLocked(prc, stable);
5544             }
5545             return provider;
5546         }
5547     }
5548
5549     public final boolean releaseProvider(IContentProvider provider, boolean stable) {
5550         if (provider == null) {
5551             return false;
5552         }
5553
5554         IBinder jBinder = provider.asBinder();
5555         synchronized (mProviderMap) {
5556             ProviderRefCount prc = mProviderRefCountMap.get(jBinder);
5557             if (prc == null) {
5558                 // The provider has no ref count, no release is needed.
5559                 return false;
5560             }
5561
5562             boolean lastRef = false;
5563             if (stable) {
5564                 if (prc.stableCount == 0) {
5565                     if (DEBUG_PROVIDER) Slog.v(TAG,
5566                             "releaseProvider: stable ref count already 0, how?");
5567                     return false;
5568                 }
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
5576                     // doing so.
5577                     lastRef = prc.unstableCount == 0;
5578                     try {
5579                         if (DEBUG_PROVIDER) {
5580                             Slog.v(TAG, "releaseProvider: No longer stable w/lastRef="
5581                                     + lastRef + " - " + prc.holder.info.name);
5582                         }
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
5587                     }
5588                 }
5589             } else {
5590                 if (prc.unstableCount == 0) {
5591                     if (DEBUG_PROVIDER) Slog.v(TAG,
5592                             "releaseProvider: unstable ref count already 0, how?");
5593                     return false;
5594                 }
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;
5601                     if (!lastRef) {
5602                         try {
5603                             if (DEBUG_PROVIDER) {
5604                                 Slog.v(TAG, "releaseProvider: No longer unstable - "
5605                                         + prc.holder.info.name);
5606                             }
5607                             ActivityManagerNative.getDefault().refContentProvider(
5608                                     prc.holder.connection, 0, -1);
5609                         } catch (RemoteException e) {
5610                             //do nothing content provider object is dead any way
5611                         }
5612                     }
5613                 }
5614             }
5615
5616             if (lastRef) {
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);
5626                     }
5627                     prc.removePending = true;
5628                     Message msg = mH.obtainMessage(H.REMOVE_PROVIDER, prc);
5629                     mH.sendMessage(msg);
5630                 } else {
5631                     Slog.w(TAG, "Duplicate remove pending of provider " + prc.holder.info.name);
5632                 }
5633             }
5634             return true;
5635         }
5636     }
5637
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");
5646                 return;
5647             }
5648
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;
5653
5654             final IBinder jBinder = prc.holder.provider.asBinder();
5655             ProviderRefCount existingPrc = mProviderRefCountMap.get(jBinder);
5656             if (existingPrc == prc) {
5657                 mProviderRefCountMap.remove(jBinder);
5658             }
5659
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);
5665                 }
5666             }
5667         }
5668
5669         try {
5670             if (DEBUG_PROVIDER) {
5671                 Slog.v(TAG, "removeProvider: Invoking ActivityManagerNative."
5672                         + "removeContentProvider(" + prc.holder.info.name + ")");
5673             }
5674             ActivityManagerNative.getDefault().removeContentProvider(
5675                     prc.holder.connection, false);
5676         } catch (RemoteException e) {
5677             //do nothing content provider object is dead any way
5678         }
5679     }
5680
5681     final void handleUnstableProviderDied(IBinder provider, boolean fromClient) {
5682         synchronized (mProviderMap) {
5683             handleUnstableProviderDiedLocked(provider, fromClient);
5684         }
5685     }
5686
5687     final void handleUnstableProviderDiedLocked(IBinder provider, boolean fromClient) {
5688         ProviderRefCount prc = mProviderRefCountMap.get(provider);
5689         if (prc != null) {
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);
5698                 }
5699             }
5700
5701             if (fromClient) {
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
5706                 // notification).
5707                 try {
5708                     ActivityManagerNative.getDefault().unstableProviderDied(
5709                             prc.holder.connection);
5710                 } catch (RemoteException e) {
5711                     //do nothing content provider object is dead any way
5712                 }
5713             }
5714         }
5715     }
5716
5717     final void appNotRespondingViaProvider(IBinder provider) {
5718         synchronized (mProviderMap) {
5719             ProviderRefCount prc = mProviderRefCountMap.get(provider);
5720             if (prc != null) {
5721                 try {
5722                     ActivityManagerNative.getDefault()
5723                             .appNotRespondingViaProvider(prc.holder.connection);
5724                 } catch (RemoteException e) {
5725                     throw e.rethrowFromSystemServer();
5726                 }
5727             }
5728         }
5729     }
5730
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);
5735
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);
5744             } else {
5745                 mProviderMap.put(key, pcr);
5746             }
5747         }
5748         return pcr;
5749     }
5750
5751     /**
5752      * Installs the provider.
5753      *
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).
5759      *
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.
5764      */
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 + ": "
5773                         + info.name);
5774             }
5775             Context c = null;
5776             ApplicationInfo ai = info.applicationInfo;
5777             if (context.getPackageName().equals(ai.packageName)) {
5778                 c = context;
5779             } else if (mInitialApplication != null &&
5780                     mInitialApplication.getPackageName().equals(ai.packageName)) {
5781                 c = mInitialApplication;
5782             } else {
5783                 try {
5784                     c = context.createPackageContext(ai.packageName,
5785                             Context.CONTEXT_INCLUDE_CODE);
5786                 } catch (PackageManager.NameNotFoundException e) {
5787                     // Ignore
5788                 }
5789             }
5790             if (c == null) {
5791                 Slog.w(TAG, "Unable to get context for package " +
5792                       ai.packageName +
5793                       " while loading content provider " +
5794                       info.name);
5795                 return null;
5796             }
5797             try {
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);
5806                     return null;
5807                 }
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);
5817                 }
5818                 return null;
5819             }
5820         } else {
5821             provider = holder.provider;
5822             if (DEBUG_PROVIDER) Slog.v(TAG, "Installing external provider " + info.authority + ": "
5823                     + info.name);
5824         }
5825
5826         IActivityManager.ContentProviderHolder retHolder;
5827
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);
5835                 if (pr != null) {
5836                     if (DEBUG_PROVIDER) {
5837                         Slog.v(TAG, "installProvider: lost the race, "
5838                                 + "using existing local provider");
5839                     }
5840                     provider = pr.mProvider;
5841                 } else {
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);
5848                 }
5849                 retHolder = pr.mHolder;
5850             } else {
5851                 ProviderRefCount prc = mProviderRefCountMap.get(jBinder);
5852                 if (prc != null) {
5853                     if (DEBUG_PROVIDER) {
5854                         Slog.v(TAG, "installProvider: lost the race, updating ref count");
5855                     }
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
5859                     // system process).
5860                     if (!noReleaseNeeded) {
5861                         incProviderRefLocked(prc, stable);
5862                         try {
5863                             ActivityManagerNative.getDefault().removeContentProvider(
5864                                     holder.connection, stable);
5865                         } catch (RemoteException e) {
5866                             //do nothing content provider object is dead any way
5867                         }
5868                     }
5869                 } else {
5870                     ProviderClientRecord client = installProviderAuthoritiesLocked(
5871                             provider, localProvider, holder);
5872                     if (noReleaseNeeded) {
5873                         prc = new ProviderRefCount(holder, client, 1000, 1000);
5874                     } else {
5875                         prc = stable
5876                                 ? new ProviderRefCount(holder, client, 1, 0)
5877                                 : new ProviderRefCount(holder, client, 0, 1);
5878                     }
5879                     mProviderRefCountMap.put(jBinder, prc);
5880                 }
5881                 retHolder = prc.holder;
5882             }
5883         }
5884
5885         return retHolder;
5886     }
5887
5888     private void attach(boolean system) {
5889         sCurrentActivityThread = this;
5890         mSystemThread = system;
5891         if (!system) {
5892             ViewRootImpl.addFirstDrawHandler(new Runnable() {
5893                 @Override
5894                 public void run() {
5895                     ensureJitEnabled();
5896                 }
5897             });
5898             android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",
5899                                                     UserHandle.myUserId());
5900             RuntimeInit.setApplicationObject(mAppThread.asBinder());
5901             final IActivityManager mgr = ActivityManagerNative.getDefault();
5902             try {
5903                 mgr.attachApplication(mAppThread);
5904             } catch (RemoteException ex) {
5905                 throw ex.rethrowFromSystemServer();
5906             }
5907             // Watch for getting close to heap limit.
5908             BinderInternal.addGcWatcher(new Runnable() {
5909                 @Override public void run() {
5910                     if (!mSomeActivitiesChanged) {
5911                         return;
5912                     }
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;
5921                         try {
5922                             mgr.releaseSomeActivities(mAppThread);
5923                         } catch (RemoteException e) {
5924                             throw e.rethrowFromSystemServer();
5925                         }
5926                     }
5927                 }
5928             });
5929         } else {
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());
5934             try {
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);
5943             }
5944         }
5945
5946         // add dropbox logging to libcore
5947         DropBox.setReporter(new DropBoxReporter());
5948
5949         ViewRootImpl.addConfigCallback(new ComponentCallbacks2() {
5950             @Override
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());
5959
5960                         // This actually changed the resources!  Tell
5961                         // everyone about it.
5962                         if (mPendingConfiguration == null ||
5963                                 mPendingConfiguration.isOtherSeqNewer(newConfig)) {
5964                             mPendingConfiguration = newConfig;
5965
5966                             sendMessage(H.CONFIGURATION_CHANGED, newConfig);
5967                         }
5968                     }
5969                 }
5970             }
5971             @Override
5972             public void onLowMemory() {
5973             }
5974             @Override
5975             public void onTrimMemory(int level) {
5976             }
5977         });
5978     }
5979
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
5983         // process.
5984         if (!ActivityManager.isHighEndGfx()) {
5985             ThreadedRenderer.disable(true);
5986         } else {
5987             ThreadedRenderer.enableForegroundTrimming();
5988         }
5989         ActivityThread thread = new ActivityThread();
5990         thread.attach(true);
5991         return thread;
5992     }
5993
5994     public final void installSystemProviders(List<ProviderInfo> providers) {
5995         if (providers != null) {
5996             installContentProviders(mInitialApplication, providers);
5997         }
5998     }
5999
6000     public int getIntCoreSetting(String key, int defaultValue) {
6001         synchronized (mResourcesManager) {
6002             if (mCoreSettings != null) {
6003                 return mCoreSettings.getInt(key, defaultValue);
6004             }
6005             return defaultValue;
6006         }
6007     }
6008
6009     private static class EventLoggingReporter implements EventLogger.Reporter {
6010         @Override
6011         public void report (int code, Object... list) {
6012             EventLog.writeEvent(code, list);
6013         }
6014     }
6015
6016     private class DropBoxReporter implements DropBox.Reporter {
6017
6018         private DropBoxManager dropBox;
6019
6020         public DropBoxReporter() {}
6021
6022         @Override
6023         public void addData(String tag, byte[] data, int flags) {
6024             ensureInitialized();
6025             dropBox.addData(tag, data, flags);
6026         }
6027
6028         @Override
6029         public void addText(String tag, String data) {
6030             ensureInitialized();
6031             dropBox.addText(tag, data);
6032         }
6033
6034         private synchronized void ensureInitialized() {
6035             if (dropBox == null) {
6036                 dropBox = (DropBoxManager) getSystemContext().getSystemService(Context.DROPBOX_SERVICE);
6037             }
6038         }
6039     }
6040
6041     public static void main(String[] args) {
6042         Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");
6043         SamplingProfilerIntegration.start();
6044
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);
6049
6050         Environment.initForCurrentUser();
6051
6052         // Set the reporter for event logging in libcore
6053         EventLogger.setReporter(new EventLoggingReporter());
6054
6055         // Make sure TrustedCertificateStore looks in the right place for CA certificates
6056         final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
6057         TrustedCertificateStore.setDefaultUserDirectory(configDir);
6058
6059         Process.setArgV0("<pre-initialized>");
6060
6061         Looper.prepareMainLooper();
6062
6063         ActivityThread thread = new ActivityThread();
6064         thread.attach(false);
6065
6066         if (sMainThreadHandler == null) {
6067             sMainThreadHandler = thread.getHandler();
6068         }
6069
6070         if (false) {
6071             Looper.myLooper().setMessageLogging(new
6072                     LogPrinter(Log.DEBUG, "ActivityThread"));
6073         }
6074
6075         // End of event ActivityThreadMain.
6076         Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6077         Looper.loop();
6078
6079         throw new RuntimeException("Main thread loop unexpectedly exited");
6080     }
6081 }