ActivityThread.java revision 8f3b174d90e3bf2093751fb1a1bd0603adac0222
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
17package android.app;
18
19import android.annotation.NonNull;
20import android.annotation.Nullable;
21import android.app.assist.AssistContent;
22import android.app.assist.AssistStructure;
23import android.app.backup.BackupAgent;
24import android.content.BroadcastReceiver;
25import android.content.ComponentCallbacks2;
26import android.content.ComponentName;
27import android.content.ContentProvider;
28import android.content.Context;
29import android.content.IContentProvider;
30import android.content.Intent;
31import android.content.IIntentReceiver;
32import android.content.pm.ActivityInfo;
33import android.content.pm.ApplicationInfo;
34import android.content.pm.IPackageManager;
35import android.content.pm.InstrumentationInfo;
36import android.content.pm.PackageInfo;
37import android.content.pm.PackageManager;
38import android.content.pm.PackageManager.NameNotFoundException;
39import android.content.pm.ProviderInfo;
40import android.content.pm.ServiceInfo;
41import android.content.res.AssetManager;
42import android.content.res.CompatibilityInfo;
43import android.content.res.Configuration;
44import android.content.res.Resources;
45import android.content.res.Resources.Theme;
46import android.database.sqlite.SQLiteDatabase;
47import android.database.sqlite.SQLiteDebug;
48import android.database.sqlite.SQLiteDebug.DbStats;
49import android.graphics.Bitmap;
50import android.graphics.Canvas;
51import android.hardware.display.DisplayManagerGlobal;
52import android.net.ConnectivityManager;
53import android.net.IConnectivityManager;
54import android.net.Network;
55import android.net.Proxy;
56import android.net.ProxyInfo;
57import android.net.Uri;
58import android.os.AsyncTask;
59import android.os.Binder;
60import android.os.Build;
61import android.os.Bundle;
62import android.os.Debug;
63import android.os.DropBoxManager;
64import android.os.Environment;
65import android.os.GraphicsEnvironment;
66import android.os.Handler;
67import android.os.IBinder;
68import android.os.LocaleList;
69import android.os.Looper;
70import android.os.Message;
71import android.os.MessageQueue;
72import android.os.Parcel;
73import android.os.ParcelFileDescriptor;
74import android.os.PersistableBundle;
75import android.os.Process;
76import android.os.RemoteException;
77import android.os.ServiceManager;
78import android.os.StrictMode;
79import android.os.SystemClock;
80import android.os.SystemProperties;
81import android.os.Trace;
82import android.os.TransactionTooLargeException;
83import android.os.UserHandle;
84import android.provider.BlockedNumberContract;
85import android.provider.CalendarContract;
86import android.provider.CallLog;
87import android.provider.ContactsContract;
88import android.provider.Downloads;
89import android.provider.Settings;
90import android.security.NetworkSecurityPolicy;
91import android.security.net.config.NetworkSecurityConfigProvider;
92import android.service.autofill.AutoFillService;
93import android.service.autofill.IAutoFillAppCallback;
94import android.service.voice.VoiceInteractionSession;
95import android.util.AndroidRuntimeException;
96import android.util.ArrayMap;
97import android.util.DisplayMetrics;
98import android.util.EventLog;
99import android.util.Log;
100import android.util.LogPrinter;
101import android.util.Pair;
102import android.util.PrintWriterPrinter;
103import android.util.Slog;
104import android.util.SparseIntArray;
105import android.util.SuperNotCalledException;
106import android.view.ContextThemeWrapper;
107import android.view.Display;
108import android.view.ThreadedRenderer;
109import android.view.View;
110import android.view.ViewDebug;
111import android.view.ViewManager;
112import android.view.ViewRootImpl;
113import android.view.Window;
114import android.view.WindowManager;
115import android.view.WindowManagerGlobal;
116import android.renderscript.RenderScriptCacheDir;
117import android.webkit.WebView;
118
119import com.android.internal.annotations.GuardedBy;
120import com.android.internal.app.IVoiceInteractor;
121import com.android.internal.content.ReferrerIntent;
122import com.android.internal.os.BinderInternal;
123import com.android.internal.os.RuntimeInit;
124import com.android.internal.os.SamplingProfilerIntegration;
125import com.android.internal.os.SomeArgs;
126import com.android.internal.util.ArrayUtils;
127import com.android.internal.util.FastPrintWriter;
128import com.android.org.conscrypt.OpenSSLSocketImpl;
129import com.android.org.conscrypt.TrustedCertificateStore;
130import com.google.android.collect.Lists;
131
132import java.io.File;
133import java.io.FileDescriptor;
134import java.io.FileOutputStream;
135import java.io.IOException;
136import java.io.PrintWriter;
137import java.lang.ref.WeakReference;
138import java.lang.reflect.Field;
139import java.net.InetAddress;
140import java.text.DateFormat;
141import java.util.ArrayList;
142import java.util.List;
143import java.util.Locale;
144import java.util.Map;
145import java.util.Objects;
146import java.util.TimeZone;
147
148import libcore.io.DropBox;
149import libcore.io.EventLogger;
150import libcore.io.IoUtils;
151import libcore.net.event.NetworkEventDispatcher;
152import dalvik.system.CloseGuard;
153import dalvik.system.VMDebug;
154import dalvik.system.VMRuntime;
155import org.apache.harmony.dalvik.ddmc.DdmVmInternal;
156
157final class RemoteServiceException extends AndroidRuntimeException {
158    public RemoteServiceException(String msg) {
159        super(msg);
160    }
161}
162
163/**
164 * This manages the execution of the main thread in an
165 * application process, scheduling and executing activities,
166 * broadcasts, and other operations on it as the activity
167 * manager requests.
168 *
169 * {@hide}
170 */
171public final class ActivityThread {
172    /** @hide */
173    public static final String TAG = "ActivityThread";
174    private static final android.graphics.Bitmap.Config THUMBNAIL_FORMAT = Bitmap.Config.RGB_565;
175    static final boolean localLOGV = false;
176    static final boolean DEBUG_MESSAGES = false;
177    /** @hide */
178    public static final boolean DEBUG_BROADCAST = false;
179    private static final boolean DEBUG_RESULTS = false;
180    private static final boolean DEBUG_BACKUP = false;
181    public static final boolean DEBUG_CONFIGURATION = false;
182    private static final boolean DEBUG_SERVICE = false;
183    private static final boolean DEBUG_MEMORY_TRIM = false;
184    private static final boolean DEBUG_PROVIDER = false;
185    private static final boolean DEBUG_ORDER = false;
186    private static final long MIN_TIME_BETWEEN_GCS = 5*1000;
187    private static final int SQLITE_MEM_RELEASED_EVENT_LOG_TAG = 75003;
188    private static final int LOG_AM_ON_PAUSE_CALLED = 30021;
189    private static final int LOG_AM_ON_RESUME_CALLED = 30022;
190    private static final int LOG_AM_ON_STOP_CALLED = 30049;
191
192    /** Type for IActivityManager.serviceDoneExecuting: anonymous operation */
193    public static final int SERVICE_DONE_EXECUTING_ANON = 0;
194    /** Type for IActivityManager.serviceDoneExecuting: done with an onStart call */
195    public static final int SERVICE_DONE_EXECUTING_START = 1;
196    /** Type for IActivityManager.serviceDoneExecuting: done stopping (destroying) service */
197    public static final int SERVICE_DONE_EXECUTING_STOP = 2;
198
199    // Details for pausing activity.
200    private static final int USER_LEAVING = 1;
201    private static final int DONT_REPORT = 2;
202
203    // Whether to invoke an activity callback after delivering new configuration.
204    private static final boolean REPORT_TO_ACTIVITY = true;
205
206    private ContextImpl mSystemContext;
207
208    static volatile IPackageManager sPackageManager;
209
210    final ApplicationThread mAppThread = new ApplicationThread();
211    final Looper mLooper = Looper.myLooper();
212    final H mH = new H();
213    final ArrayMap<IBinder, ActivityClientRecord> mActivities = new ArrayMap<>();
214    // List of new activities (via ActivityRecord.nextIdle) that should
215    // be reported when next we idle.
216    ActivityClientRecord mNewActivities = null;
217    // Number of activities that are currently visible on-screen.
218    int mNumVisibleActivities = 0;
219    ArrayList<WeakReference<AssistStructure>> mLastAssistStructures = new ArrayList<>();
220    private int mLastSessionId;
221    final ArrayMap<IBinder, Service> mServices = new ArrayMap<>();
222    AppBindData mBoundApplication;
223    Profiler mProfiler;
224    int mCurDefaultDisplayDpi;
225    boolean mDensityCompatMode;
226    Configuration mConfiguration;
227    Configuration mCompatConfiguration;
228    Application mInitialApplication;
229    final ArrayList<Application> mAllApplications
230            = new ArrayList<Application>();
231    // set of instantiated backup agents, keyed by package name
232    final ArrayMap<String, BackupAgent> mBackupAgents = new ArrayMap<String, BackupAgent>();
233    /** Reference to singleton {@link ActivityThread} */
234    private static volatile ActivityThread sCurrentActivityThread;
235    Instrumentation mInstrumentation;
236    String mInstrumentationPackageName = null;
237    String mInstrumentationAppDir = null;
238    String[] mInstrumentationSplitAppDirs = null;
239    String mInstrumentationLibDir = null;
240    String mInstrumentedAppDir = null;
241    String[] mInstrumentedSplitAppDirs = null;
242    String mInstrumentedLibDir = null;
243    boolean mSystemThread = false;
244    boolean mJitEnabled = false;
245    boolean mSomeActivitiesChanged = false;
246    boolean mUpdatingSystemConfig = false;
247
248    // These can be accessed by multiple threads; mResourcesManager is the lock.
249    // XXX For now we keep around information about all packages we have
250    // seen, not removing entries from this map.
251    // NOTE: The activity and window managers need to call in to
252    // ActivityThread to do things like update resource configurations,
253    // which means this lock gets held while the activity and window managers
254    // holds their own lock.  Thus you MUST NEVER call back into the activity manager
255    // or window manager or anything that depends on them while holding this lock.
256    // These LoadedApk are only valid for the userId that we're running as.
257    @GuardedBy("mResourcesManager")
258    final ArrayMap<String, WeakReference<LoadedApk>> mPackages = new ArrayMap<>();
259    @GuardedBy("mResourcesManager")
260    final ArrayMap<String, WeakReference<LoadedApk>> mResourcePackages = new ArrayMap<>();
261    @GuardedBy("mResourcesManager")
262    final ArrayList<ActivityClientRecord> mRelaunchingActivities = new ArrayList<>();
263    @GuardedBy("mResourcesManager")
264    Configuration mPendingConfiguration = null;
265    // Because we merge activity relaunch operations we can't depend on the ordering provided by
266    // the handler messages. We need to introduce secondary ordering mechanism, which will allow
267    // us to drop certain events, if we know that they happened before relaunch we already executed.
268    // This represents the order of receiving the request from AM.
269    @GuardedBy("mResourcesManager")
270    int mLifecycleSeq = 0;
271
272    private final ResourcesManager mResourcesManager;
273
274    private static final class ProviderKey {
275        final String authority;
276        final int userId;
277
278        public ProviderKey(String authority, int userId) {
279            this.authority = authority;
280            this.userId = userId;
281        }
282
283        @Override
284        public boolean equals(Object o) {
285            if (o instanceof ProviderKey) {
286                final ProviderKey other = (ProviderKey) o;
287                return Objects.equals(authority, other.authority) && userId == other.userId;
288            }
289            return false;
290        }
291
292        @Override
293        public int hashCode() {
294            return ((authority != null) ? authority.hashCode() : 0) ^ userId;
295        }
296    }
297
298    // The lock of mProviderMap protects the following variables.
299    final ArrayMap<ProviderKey, ProviderClientRecord> mProviderMap
300        = new ArrayMap<ProviderKey, ProviderClientRecord>();
301    final ArrayMap<IBinder, ProviderRefCount> mProviderRefCountMap
302        = new ArrayMap<IBinder, ProviderRefCount>();
303    final ArrayMap<IBinder, ProviderClientRecord> mLocalProviders
304        = new ArrayMap<IBinder, ProviderClientRecord>();
305    final ArrayMap<ComponentName, ProviderClientRecord> mLocalProvidersByName
306            = new ArrayMap<ComponentName, ProviderClientRecord>();
307
308    final ArrayMap<Activity, ArrayList<OnActivityPausedListener>> mOnPauseListeners
309        = new ArrayMap<Activity, ArrayList<OnActivityPausedListener>>();
310
311    final GcIdler mGcIdler = new GcIdler();
312    boolean mGcIdlerScheduled = false;
313
314    static volatile Handler sMainThreadHandler;  // set once in main()
315
316    Bundle mCoreSettings = null;
317
318    static final class ActivityClientRecord {
319        IBinder token;
320        int ident;
321        Intent intent;
322        String referrer;
323        IVoiceInteractor voiceInteractor;
324        Bundle state;
325        PersistableBundle persistentState;
326        Activity activity;
327        Window window;
328        Activity parent;
329        String embeddedID;
330        Activity.NonConfigurationInstances lastNonConfigurationInstances;
331        boolean paused;
332        boolean stopped;
333        boolean hideForNow;
334        Configuration newConfig;
335        Configuration createdConfig;
336        Configuration overrideConfig;
337        // Used for consolidating configs before sending on to Activity.
338        private Configuration tmpConfig = new Configuration();
339        ActivityClientRecord nextIdle;
340
341        ProfilerInfo profilerInfo;
342
343        ActivityInfo activityInfo;
344        CompatibilityInfo compatInfo;
345        LoadedApk packageInfo;
346
347        List<ResultInfo> pendingResults;
348        List<ReferrerIntent> pendingIntents;
349
350        boolean startsNotResumed;
351        boolean isForward;
352        int pendingConfigChanges;
353        boolean onlyLocalRequest;
354
355        Window mPendingRemoveWindow;
356        WindowManager mPendingRemoveWindowManager;
357        boolean mPreserveWindow;
358
359        // Set for relaunch requests, indicates the order number of the relaunch operation, so it
360        // can be compared with other lifecycle operations.
361        int relaunchSeq = 0;
362
363        // Can only be accessed from the UI thread. This represents the latest processed message
364        // that is related to lifecycle events/
365        int lastProcessedSeq = 0;
366
367        ActivityClientRecord() {
368            parent = null;
369            embeddedID = null;
370            paused = false;
371            stopped = false;
372            hideForNow = false;
373            nextIdle = null;
374        }
375
376        public boolean isPreHoneycomb() {
377            if (activity != null) {
378                return activity.getApplicationInfo().targetSdkVersion
379                        < android.os.Build.VERSION_CODES.HONEYCOMB;
380            }
381            return false;
382        }
383
384        public boolean isPersistable() {
385            return activityInfo.persistableMode == ActivityInfo.PERSIST_ACROSS_REBOOTS;
386        }
387
388        public String toString() {
389            ComponentName componentName = intent != null ? intent.getComponent() : null;
390            return "ActivityRecord{"
391                + Integer.toHexString(System.identityHashCode(this))
392                + " token=" + token + " " + (componentName == null
393                        ? "no component name" : componentName.toShortString())
394                + "}";
395        }
396
397        public String getStateString() {
398            StringBuilder sb = new StringBuilder();
399            sb.append("ActivityClientRecord{");
400            sb.append("paused=").append(paused);
401            sb.append(", stopped=").append(stopped);
402            sb.append(", hideForNow=").append(hideForNow);
403            sb.append(", startsNotResumed=").append(startsNotResumed);
404            sb.append(", isForward=").append(isForward);
405            sb.append(", pendingConfigChanges=").append(pendingConfigChanges);
406            sb.append(", onlyLocalRequest=").append(onlyLocalRequest);
407            sb.append(", preserveWindow=").append(mPreserveWindow);
408            if (activity != null) {
409                sb.append(", Activity{");
410                sb.append("resumed=").append(activity.mResumed);
411                sb.append(", stopped=").append(activity.mStopped);
412                sb.append(", finished=").append(activity.isFinishing());
413                sb.append(", destroyed=").append(activity.isDestroyed());
414                sb.append(", startedActivity=").append(activity.mStartedActivity);
415                sb.append(", temporaryPause=").append(activity.mTemporaryPause);
416                sb.append(", changingConfigurations=").append(activity.mChangingConfigurations);
417                sb.append(", visibleBehind=").append(activity.mVisibleBehind);
418                sb.append("}");
419            }
420            sb.append("}");
421            return sb.toString();
422        }
423    }
424
425    final class ProviderClientRecord {
426        final String[] mNames;
427        final IContentProvider mProvider;
428        final ContentProvider mLocalProvider;
429        final ContentProviderHolder mHolder;
430
431        ProviderClientRecord(String[] names, IContentProvider provider,
432                ContentProvider localProvider, ContentProviderHolder holder) {
433            mNames = names;
434            mProvider = provider;
435            mLocalProvider = localProvider;
436            mHolder = holder;
437        }
438    }
439
440    static final class NewIntentData {
441        List<ReferrerIntent> intents;
442        IBinder token;
443        boolean andPause;
444        public String toString() {
445            return "NewIntentData{intents=" + intents + " token=" + token
446                    + " andPause=" + andPause +"}";
447        }
448    }
449
450    static final class ReceiverData extends BroadcastReceiver.PendingResult {
451        public ReceiverData(Intent intent, int resultCode, String resultData, Bundle resultExtras,
452                boolean ordered, boolean sticky, IBinder token, int sendingUser) {
453            super(resultCode, resultData, resultExtras, TYPE_COMPONENT, ordered, sticky,
454                    token, sendingUser, intent.getFlags());
455            this.intent = intent;
456        }
457
458        Intent intent;
459        ActivityInfo info;
460        CompatibilityInfo compatInfo;
461        public String toString() {
462            return "ReceiverData{intent=" + intent + " packageName=" +
463                    info.packageName + " resultCode=" + getResultCode()
464                    + " resultData=" + getResultData() + " resultExtras="
465                    + getResultExtras(false) + "}";
466        }
467    }
468
469    static final class CreateBackupAgentData {
470        ApplicationInfo appInfo;
471        CompatibilityInfo compatInfo;
472        int backupMode;
473        public String toString() {
474            return "CreateBackupAgentData{appInfo=" + appInfo
475                    + " backupAgent=" + appInfo.backupAgentName
476                    + " mode=" + backupMode + "}";
477        }
478    }
479
480    static final class CreateServiceData {
481        IBinder token;
482        ServiceInfo info;
483        CompatibilityInfo compatInfo;
484        Intent intent;
485        public String toString() {
486            return "CreateServiceData{token=" + token + " className="
487            + info.name + " packageName=" + info.packageName
488            + " intent=" + intent + "}";
489        }
490    }
491
492    static final class BindServiceData {
493        IBinder token;
494        Intent intent;
495        boolean rebind;
496        public String toString() {
497            return "BindServiceData{token=" + token + " intent=" + intent + "}";
498        }
499    }
500
501    static final class ServiceArgsData {
502        IBinder token;
503        boolean taskRemoved;
504        int startId;
505        int flags;
506        Intent args;
507        public String toString() {
508            return "ServiceArgsData{token=" + token + " startId=" + startId
509            + " args=" + args + "}";
510        }
511    }
512
513    static final class AppBindData {
514        LoadedApk info;
515        String processName;
516        ApplicationInfo appInfo;
517        List<ProviderInfo> providers;
518        ComponentName instrumentationName;
519        Bundle instrumentationArgs;
520        IInstrumentationWatcher instrumentationWatcher;
521        IUiAutomationConnection instrumentationUiAutomationConnection;
522        int debugMode;
523        boolean enableBinderTracking;
524        boolean trackAllocation;
525        boolean restrictedBackupMode;
526        boolean persistent;
527        Configuration config;
528        CompatibilityInfo compatInfo;
529        String buildSerial;
530
531        /** Initial values for {@link Profiler}. */
532        ProfilerInfo initProfilerInfo;
533
534        public String toString() {
535            return "AppBindData{appInfo=" + appInfo + "}";
536        }
537    }
538
539    static final class Profiler {
540        String profileFile;
541        ParcelFileDescriptor profileFd;
542        int samplingInterval;
543        boolean autoStopProfiler;
544        boolean profiling;
545        boolean handlingProfiling;
546        public void setProfiler(ProfilerInfo profilerInfo) {
547            ParcelFileDescriptor fd = profilerInfo.profileFd;
548            if (profiling) {
549                if (fd != null) {
550                    try {
551                        fd.close();
552                    } catch (IOException e) {
553                        // Ignore
554                    }
555                }
556                return;
557            }
558            if (profileFd != null) {
559                try {
560                    profileFd.close();
561                } catch (IOException e) {
562                    // Ignore
563                }
564            }
565            profileFile = profilerInfo.profileFile;
566            profileFd = fd;
567            samplingInterval = profilerInfo.samplingInterval;
568            autoStopProfiler = profilerInfo.autoStopProfiler;
569        }
570        public void startProfiling() {
571            if (profileFd == null || profiling) {
572                return;
573            }
574            try {
575                int bufferSize = SystemProperties.getInt("debug.traceview-buffer-size-mb", 8);
576                VMDebug.startMethodTracing(profileFile, profileFd.getFileDescriptor(),
577                        bufferSize * 1024 * 1024, 0, samplingInterval != 0, samplingInterval);
578                profiling = true;
579            } catch (RuntimeException e) {
580                Slog.w(TAG, "Profiling failed on path " + profileFile);
581                try {
582                    profileFd.close();
583                    profileFd = null;
584                } catch (IOException e2) {
585                    Slog.w(TAG, "Failure closing profile fd", e2);
586                }
587            }
588        }
589        public void stopProfiling() {
590            if (profiling) {
591                profiling = false;
592                Debug.stopMethodTracing();
593                if (profileFd != null) {
594                    try {
595                        profileFd.close();
596                    } catch (IOException e) {
597                    }
598                }
599                profileFd = null;
600                profileFile = null;
601            }
602        }
603    }
604
605    static final class DumpComponentInfo {
606        ParcelFileDescriptor fd;
607        IBinder token;
608        String prefix;
609        String[] args;
610    }
611
612    static final class ResultData {
613        IBinder token;
614        List<ResultInfo> results;
615        public String toString() {
616            return "ResultData{token=" + token + " results" + results + "}";
617        }
618    }
619
620    static final class ContextCleanupInfo {
621        ContextImpl context;
622        String what;
623        String who;
624    }
625
626    static final class DumpHeapData {
627        String path;
628        ParcelFileDescriptor fd;
629    }
630
631    static final class UpdateCompatibilityData {
632        String pkg;
633        CompatibilityInfo info;
634    }
635
636    static final class RequestAssistContextExtras {
637        IBinder activityToken;
638        IBinder requestToken;
639        int requestType;
640        int sessionId;
641        int flags;
642    }
643
644    static final class ActivityConfigChangeData {
645        final IBinder activityToken;
646        final Configuration overrideConfig;
647        public ActivityConfigChangeData(IBinder token, Configuration config) {
648            activityToken = token;
649            overrideConfig = config;
650        }
651    }
652
653    private class ApplicationThread extends IApplicationThread.Stub {
654        private static final String DB_INFO_FORMAT = "  %8s %8s %14s %14s  %s";
655
656        private int mLastProcessState = -1;
657
658        private void updatePendingConfiguration(Configuration config) {
659            synchronized (mResourcesManager) {
660                if (mPendingConfiguration == null ||
661                        mPendingConfiguration.isOtherSeqNewer(config)) {
662                    mPendingConfiguration = config;
663                }
664            }
665        }
666
667        public final void schedulePauseActivity(IBinder token, boolean finished,
668                boolean userLeaving, int configChanges, boolean dontReport) {
669            int seq = getLifecycleSeq();
670            if (DEBUG_ORDER) Slog.d(TAG, "pauseActivity " + ActivityThread.this
671                    + " operation received seq: " + seq);
672            sendMessage(
673                    finished ? H.PAUSE_ACTIVITY_FINISHING : H.PAUSE_ACTIVITY,
674                    token,
675                    (userLeaving ? USER_LEAVING : 0) | (dontReport ? DONT_REPORT : 0),
676                    configChanges,
677                    seq);
678        }
679
680        public final void scheduleStopActivity(IBinder token, boolean showWindow,
681                int configChanges) {
682            int seq = getLifecycleSeq();
683            if (DEBUG_ORDER) Slog.d(TAG, "stopActivity " + ActivityThread.this
684                    + " operation received seq: " + seq);
685            sendMessage(
686                showWindow ? H.STOP_ACTIVITY_SHOW : H.STOP_ACTIVITY_HIDE,
687                token, 0, configChanges, seq);
688        }
689
690        public final void scheduleWindowVisibility(IBinder token, boolean showWindow) {
691            sendMessage(
692                showWindow ? H.SHOW_WINDOW : H.HIDE_WINDOW,
693                token);
694        }
695
696        public final void scheduleSleeping(IBinder token, boolean sleeping) {
697            sendMessage(H.SLEEPING, token, sleeping ? 1 : 0);
698        }
699
700        public final void scheduleResumeActivity(IBinder token, int processState,
701                boolean isForward, Bundle resumeArgs) {
702            int seq = getLifecycleSeq();
703            if (DEBUG_ORDER) Slog.d(TAG, "resumeActivity " + ActivityThread.this
704                    + " operation received seq: " + seq);
705            updateProcessState(processState, false);
706            sendMessage(H.RESUME_ACTIVITY, token, isForward ? 1 : 0, 0, seq);
707        }
708
709        public final void scheduleSendResult(IBinder token, List<ResultInfo> results) {
710            ResultData res = new ResultData();
711            res.token = token;
712            res.results = results;
713            sendMessage(H.SEND_RESULT, res);
714        }
715
716        // we use token to identify this activity without having to send the
717        // activity itself back to the activity manager. (matters more with ipc)
718        @Override
719        public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
720                ActivityInfo info, Configuration curConfig, Configuration overrideConfig,
721                CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor,
722                int procState, Bundle state, PersistableBundle persistentState,
723                List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents,
724                boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) {
725
726            updateProcessState(procState, false);
727
728            ActivityClientRecord r = new ActivityClientRecord();
729
730            r.token = token;
731            r.ident = ident;
732            r.intent = intent;
733            r.referrer = referrer;
734            r.voiceInteractor = voiceInteractor;
735            r.activityInfo = info;
736            r.compatInfo = compatInfo;
737            r.state = state;
738            r.persistentState = persistentState;
739
740            r.pendingResults = pendingResults;
741            r.pendingIntents = pendingNewIntents;
742
743            r.startsNotResumed = notResumed;
744            r.isForward = isForward;
745
746            r.profilerInfo = profilerInfo;
747
748            r.overrideConfig = overrideConfig;
749            updatePendingConfiguration(curConfig);
750
751            sendMessage(H.LAUNCH_ACTIVITY, r);
752        }
753
754        @Override
755        public final void scheduleRelaunchActivity(IBinder token,
756                List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents,
757                int configChanges, boolean notResumed, Configuration config,
758                Configuration overrideConfig, boolean preserveWindow) {
759            requestRelaunchActivity(token, pendingResults, pendingNewIntents,
760                    configChanges, notResumed, config, overrideConfig, true, preserveWindow);
761        }
762
763        public final void scheduleNewIntent(
764                List<ReferrerIntent> intents, IBinder token, boolean andPause) {
765            NewIntentData data = new NewIntentData();
766            data.intents = intents;
767            data.token = token;
768            data.andPause = andPause;
769
770            sendMessage(H.NEW_INTENT, data);
771        }
772
773        public final void scheduleDestroyActivity(IBinder token, boolean finishing,
774                int configChanges) {
775            sendMessage(H.DESTROY_ACTIVITY, token, finishing ? 1 : 0,
776                    configChanges);
777        }
778
779        public final void scheduleReceiver(Intent intent, ActivityInfo info,
780                CompatibilityInfo compatInfo, int resultCode, String data, Bundle extras,
781                boolean sync, int sendingUser, int processState) {
782            updateProcessState(processState, false);
783            ReceiverData r = new ReceiverData(intent, resultCode, data, extras,
784                    sync, false, mAppThread.asBinder(), sendingUser);
785            r.info = info;
786            r.compatInfo = compatInfo;
787            sendMessage(H.RECEIVER, r);
788        }
789
790        public final void scheduleCreateBackupAgent(ApplicationInfo app,
791                CompatibilityInfo compatInfo, int backupMode) {
792            CreateBackupAgentData d = new CreateBackupAgentData();
793            d.appInfo = app;
794            d.compatInfo = compatInfo;
795            d.backupMode = backupMode;
796
797            sendMessage(H.CREATE_BACKUP_AGENT, d);
798        }
799
800        public final void scheduleDestroyBackupAgent(ApplicationInfo app,
801                CompatibilityInfo compatInfo) {
802            CreateBackupAgentData d = new CreateBackupAgentData();
803            d.appInfo = app;
804            d.compatInfo = compatInfo;
805
806            sendMessage(H.DESTROY_BACKUP_AGENT, d);
807        }
808
809        public final void scheduleCreateService(IBinder token,
810                ServiceInfo info, CompatibilityInfo compatInfo, int processState) {
811            updateProcessState(processState, false);
812            CreateServiceData s = new CreateServiceData();
813            s.token = token;
814            s.info = info;
815            s.compatInfo = compatInfo;
816
817            sendMessage(H.CREATE_SERVICE, s);
818        }
819
820        public final void scheduleBindService(IBinder token, Intent intent,
821                boolean rebind, int processState) {
822            updateProcessState(processState, false);
823            BindServiceData s = new BindServiceData();
824            s.token = token;
825            s.intent = intent;
826            s.rebind = rebind;
827
828            if (DEBUG_SERVICE)
829                Slog.v(TAG, "scheduleBindService token=" + token + " intent=" + intent + " uid="
830                        + Binder.getCallingUid() + " pid=" + Binder.getCallingPid());
831            sendMessage(H.BIND_SERVICE, s);
832        }
833
834        public final void scheduleUnbindService(IBinder token, Intent intent) {
835            BindServiceData s = new BindServiceData();
836            s.token = token;
837            s.intent = intent;
838
839            sendMessage(H.UNBIND_SERVICE, s);
840        }
841
842        public final void scheduleServiceArgs(IBinder token, boolean taskRemoved, int startId,
843            int flags ,Intent args) {
844            ServiceArgsData s = new ServiceArgsData();
845            s.token = token;
846            s.taskRemoved = taskRemoved;
847            s.startId = startId;
848            s.flags = flags;
849            s.args = args;
850
851            sendMessage(H.SERVICE_ARGS, s);
852        }
853
854        public final void scheduleStopService(IBinder token) {
855            sendMessage(H.STOP_SERVICE, token);
856        }
857
858        public final void bindApplication(String processName, ApplicationInfo appInfo,
859                List<ProviderInfo> providers, ComponentName instrumentationName,
860                ProfilerInfo profilerInfo, Bundle instrumentationArgs,
861                IInstrumentationWatcher instrumentationWatcher,
862                IUiAutomationConnection instrumentationUiConnection, int debugMode,
863                boolean enableBinderTracking, boolean trackAllocation,
864                boolean isRestrictedBackupMode, boolean persistent, Configuration config,
865                CompatibilityInfo compatInfo, Map services, Bundle coreSettings,
866                String buildSerial) {
867
868            if (services != null) {
869                // Setup the service cache in the ServiceManager
870                ServiceManager.initServiceCache(services);
871            }
872
873            setCoreSettings(coreSettings);
874
875            AppBindData data = new AppBindData();
876            data.processName = processName;
877            data.appInfo = appInfo;
878            data.providers = providers;
879            data.instrumentationName = instrumentationName;
880            data.instrumentationArgs = instrumentationArgs;
881            data.instrumentationWatcher = instrumentationWatcher;
882            data.instrumentationUiAutomationConnection = instrumentationUiConnection;
883            data.debugMode = debugMode;
884            data.enableBinderTracking = enableBinderTracking;
885            data.trackAllocation = trackAllocation;
886            data.restrictedBackupMode = isRestrictedBackupMode;
887            data.persistent = persistent;
888            data.config = config;
889            data.compatInfo = compatInfo;
890            data.initProfilerInfo = profilerInfo;
891            data.buildSerial = buildSerial;
892            sendMessage(H.BIND_APPLICATION, data);
893        }
894
895        public final void scheduleExit() {
896            sendMessage(H.EXIT_APPLICATION, null);
897        }
898
899        public final void scheduleSuicide() {
900            sendMessage(H.SUICIDE, null);
901        }
902
903        public void scheduleConfigurationChanged(Configuration config) {
904            updatePendingConfiguration(config);
905            sendMessage(H.CONFIGURATION_CHANGED, config);
906        }
907
908        public void scheduleApplicationInfoChanged(ApplicationInfo ai) {
909            sendMessage(H.APPLICATION_INFO_CHANGED, ai);
910        }
911
912        public void updateTimeZone() {
913            TimeZone.setDefault(null);
914        }
915
916        public void clearDnsCache() {
917            // a non-standard API to get this to libcore
918            InetAddress.clearDnsCache();
919            // Allow libcore to perform the necessary actions as it sees fit upon a network
920            // configuration change.
921            NetworkEventDispatcher.getInstance().onNetworkConfigurationChanged();
922        }
923
924        public void setHttpProxy(String host, String port, String exclList, Uri pacFileUrl) {
925            final ConnectivityManager cm = ConnectivityManager.from(getSystemContext());
926            final Network network = cm.getBoundNetworkForProcess();
927            if (network != null) {
928                Proxy.setHttpProxySystemProperty(cm.getDefaultProxy());
929            } else {
930                Proxy.setHttpProxySystemProperty(host, port, exclList, pacFileUrl);
931            }
932        }
933
934        public void processInBackground() {
935            mH.removeMessages(H.GC_WHEN_IDLE);
936            mH.sendMessage(mH.obtainMessage(H.GC_WHEN_IDLE));
937        }
938
939        public void dumpService(ParcelFileDescriptor pfd, IBinder servicetoken, String[] args) {
940            DumpComponentInfo data = new DumpComponentInfo();
941            try {
942                data.fd = pfd.dup();
943                data.token = servicetoken;
944                data.args = args;
945                sendMessage(H.DUMP_SERVICE, data, 0, 0, true /*async*/);
946            } catch (IOException e) {
947                Slog.w(TAG, "dumpService failed", e);
948            } finally {
949                IoUtils.closeQuietly(pfd);
950            }
951        }
952
953        // This function exists to make sure all receiver dispatching is
954        // correctly ordered, since these are one-way calls and the binder driver
955        // applies transaction ordering per object for such calls.
956        public void scheduleRegisteredReceiver(IIntentReceiver receiver, Intent intent,
957                int resultCode, String dataStr, Bundle extras, boolean ordered,
958                boolean sticky, int sendingUser, int processState) throws RemoteException {
959            updateProcessState(processState, false);
960            receiver.performReceive(intent, resultCode, dataStr, extras, ordered,
961                    sticky, sendingUser);
962        }
963
964        @Override
965        public void scheduleLowMemory() {
966            sendMessage(H.LOW_MEMORY, null);
967        }
968
969        @Override
970        public void scheduleActivityConfigurationChanged(
971                IBinder token, Configuration overrideConfig, boolean reportToActivity) {
972            sendMessage(H.ACTIVITY_CONFIGURATION_CHANGED,
973                    new ActivityConfigChangeData(token, overrideConfig), reportToActivity ? 1 : 0);
974        }
975
976        @Override
977        public void profilerControl(boolean start, ProfilerInfo profilerInfo, int profileType) {
978            sendMessage(H.PROFILER_CONTROL, profilerInfo, start ? 1 : 0, profileType);
979        }
980
981        public void dumpHeap(boolean managed, String path, ParcelFileDescriptor fd) {
982            DumpHeapData dhd = new DumpHeapData();
983            dhd.path = path;
984            dhd.fd = fd;
985            sendMessage(H.DUMP_HEAP, dhd, managed ? 1 : 0, 0, true /*async*/);
986        }
987
988        public void attachAgent(String agent) {
989            sendMessage(H.ATTACH_AGENT, agent);
990        }
991
992        public void setSchedulingGroup(int group) {
993            // Note: do this immediately, since going into the foreground
994            // should happen regardless of what pending work we have to do
995            // and the activity manager will wait for us to report back that
996            // we are done before sending us to the background.
997            try {
998                Process.setProcessGroup(Process.myPid(), group);
999            } catch (Exception e) {
1000                Slog.w(TAG, "Failed setting process group to " + group, e);
1001            }
1002        }
1003
1004        public void dispatchPackageBroadcast(int cmd, String[] packages) {
1005            sendMessage(H.DISPATCH_PACKAGE_BROADCAST, packages, cmd);
1006        }
1007
1008        public void scheduleCrash(String msg) {
1009            sendMessage(H.SCHEDULE_CRASH, msg);
1010        }
1011
1012        public void dumpActivity(ParcelFileDescriptor pfd, IBinder activitytoken,
1013                String prefix, String[] args) {
1014            DumpComponentInfo data = new DumpComponentInfo();
1015            try {
1016                data.fd = pfd.dup();
1017                data.token = activitytoken;
1018                data.prefix = prefix;
1019                data.args = args;
1020                sendMessage(H.DUMP_ACTIVITY, data, 0, 0, true /*async*/);
1021            } catch (IOException e) {
1022                Slog.w(TAG, "dumpActivity failed", e);
1023            } finally {
1024                IoUtils.closeQuietly(pfd);
1025            }
1026        }
1027
1028        public void dumpProvider(ParcelFileDescriptor pfd, IBinder providertoken,
1029                String[] args) {
1030            DumpComponentInfo data = new DumpComponentInfo();
1031            try {
1032                data.fd = pfd.dup();
1033                data.token = providertoken;
1034                data.args = args;
1035                sendMessage(H.DUMP_PROVIDER, data, 0, 0, true /*async*/);
1036            } catch (IOException e) {
1037                Slog.w(TAG, "dumpProvider failed", e);
1038            } finally {
1039                IoUtils.closeQuietly(pfd);
1040            }
1041        }
1042
1043        @Override
1044        public void dumpMemInfo(ParcelFileDescriptor pfd, Debug.MemoryInfo mem, boolean checkin,
1045                boolean dumpFullInfo, boolean dumpDalvik, boolean dumpSummaryOnly,
1046                boolean dumpUnreachable, String[] args) {
1047            FileOutputStream fout = new FileOutputStream(pfd.getFileDescriptor());
1048            PrintWriter pw = new FastPrintWriter(fout);
1049            try {
1050                dumpMemInfo(pw, mem, checkin, dumpFullInfo, dumpDalvik, dumpSummaryOnly, dumpUnreachable);
1051            } finally {
1052                pw.flush();
1053                IoUtils.closeQuietly(pfd);
1054            }
1055        }
1056
1057        private void dumpMemInfo(PrintWriter pw, Debug.MemoryInfo memInfo, boolean checkin,
1058                boolean dumpFullInfo, boolean dumpDalvik, boolean dumpSummaryOnly, boolean dumpUnreachable) {
1059            long nativeMax = Debug.getNativeHeapSize() / 1024;
1060            long nativeAllocated = Debug.getNativeHeapAllocatedSize() / 1024;
1061            long nativeFree = Debug.getNativeHeapFreeSize() / 1024;
1062
1063            Runtime runtime = Runtime.getRuntime();
1064            runtime.gc();  // Do GC since countInstancesOfClass counts unreachable objects.
1065            long dalvikMax = runtime.totalMemory() / 1024;
1066            long dalvikFree = runtime.freeMemory() / 1024;
1067            long dalvikAllocated = dalvikMax - dalvikFree;
1068
1069            Class[] classesToCount = new Class[] {
1070                    ContextImpl.class,
1071                    Activity.class,
1072                    WebView.class,
1073                    OpenSSLSocketImpl.class
1074            };
1075            long[] instanceCounts = VMDebug.countInstancesOfClasses(classesToCount, true);
1076            long appContextInstanceCount = instanceCounts[0];
1077            long activityInstanceCount = instanceCounts[1];
1078            long webviewInstanceCount = instanceCounts[2];
1079            long openSslSocketCount = instanceCounts[3];
1080
1081            long viewInstanceCount = ViewDebug.getViewInstanceCount();
1082            long viewRootInstanceCount = ViewDebug.getViewRootImplCount();
1083            int globalAssetCount = AssetManager.getGlobalAssetCount();
1084            int globalAssetManagerCount = AssetManager.getGlobalAssetManagerCount();
1085            int binderLocalObjectCount = Debug.getBinderLocalObjectCount();
1086            int binderProxyObjectCount = Debug.getBinderProxyObjectCount();
1087            int binderDeathObjectCount = Debug.getBinderDeathObjectCount();
1088            long parcelSize = Parcel.getGlobalAllocSize();
1089            long parcelCount = Parcel.getGlobalAllocCount();
1090            SQLiteDebug.PagerStats stats = SQLiteDebug.getDatabaseInfo();
1091
1092            dumpMemInfoTable(pw, memInfo, checkin, dumpFullInfo, dumpDalvik, dumpSummaryOnly,
1093                    Process.myPid(),
1094                    (mBoundApplication != null) ? mBoundApplication.processName : "unknown",
1095                    nativeMax, nativeAllocated, nativeFree,
1096                    dalvikMax, dalvikAllocated, dalvikFree);
1097
1098            if (checkin) {
1099                // NOTE: if you change anything significant below, also consider changing
1100                // ACTIVITY_THREAD_CHECKIN_VERSION.
1101
1102                // Object counts
1103                pw.print(viewInstanceCount); pw.print(',');
1104                pw.print(viewRootInstanceCount); pw.print(',');
1105                pw.print(appContextInstanceCount); pw.print(',');
1106                pw.print(activityInstanceCount); pw.print(',');
1107
1108                pw.print(globalAssetCount); pw.print(',');
1109                pw.print(globalAssetManagerCount); pw.print(',');
1110                pw.print(binderLocalObjectCount); pw.print(',');
1111                pw.print(binderProxyObjectCount); pw.print(',');
1112
1113                pw.print(binderDeathObjectCount); pw.print(',');
1114                pw.print(openSslSocketCount); pw.print(',');
1115
1116                // SQL
1117                pw.print(stats.memoryUsed / 1024); pw.print(',');
1118                pw.print(stats.memoryUsed / 1024); pw.print(',');
1119                pw.print(stats.pageCacheOverflow / 1024); pw.print(',');
1120                pw.print(stats.largestMemAlloc / 1024);
1121                for (int i = 0; i < stats.dbStats.size(); i++) {
1122                    DbStats dbStats = stats.dbStats.get(i);
1123                    pw.print(','); pw.print(dbStats.dbName);
1124                    pw.print(','); pw.print(dbStats.pageSize);
1125                    pw.print(','); pw.print(dbStats.dbSize);
1126                    pw.print(','); pw.print(dbStats.lookaside);
1127                    pw.print(','); pw.print(dbStats.cache);
1128                    pw.print(','); pw.print(dbStats.cache);
1129                }
1130                pw.println();
1131
1132                return;
1133            }
1134
1135            pw.println(" ");
1136            pw.println(" Objects");
1137            printRow(pw, TWO_COUNT_COLUMNS, "Views:", viewInstanceCount, "ViewRootImpl:",
1138                    viewRootInstanceCount);
1139
1140            printRow(pw, TWO_COUNT_COLUMNS, "AppContexts:", appContextInstanceCount,
1141                    "Activities:", activityInstanceCount);
1142
1143            printRow(pw, TWO_COUNT_COLUMNS, "Assets:", globalAssetCount,
1144                    "AssetManagers:", globalAssetManagerCount);
1145
1146            printRow(pw, TWO_COUNT_COLUMNS, "Local Binders:", binderLocalObjectCount,
1147                    "Proxy Binders:", binderProxyObjectCount);
1148            printRow(pw, TWO_COUNT_COLUMNS, "Parcel memory:", parcelSize/1024,
1149                    "Parcel count:", parcelCount);
1150            printRow(pw, TWO_COUNT_COLUMNS, "Death Recipients:", binderDeathObjectCount,
1151                    "OpenSSL Sockets:", openSslSocketCount);
1152            printRow(pw, ONE_COUNT_COLUMN, "WebViews:", webviewInstanceCount);
1153
1154            // SQLite mem info
1155            pw.println(" ");
1156            pw.println(" SQL");
1157            printRow(pw, ONE_COUNT_COLUMN, "MEMORY_USED:", stats.memoryUsed / 1024);
1158            printRow(pw, TWO_COUNT_COLUMNS, "PAGECACHE_OVERFLOW:",
1159                    stats.pageCacheOverflow / 1024, "MALLOC_SIZE:", stats.largestMemAlloc / 1024);
1160            pw.println(" ");
1161            int N = stats.dbStats.size();
1162            if (N > 0) {
1163                pw.println(" DATABASES");
1164                printRow(pw, "  %8s %8s %14s %14s  %s", "pgsz", "dbsz", "Lookaside(b)", "cache",
1165                        "Dbname");
1166                for (int i = 0; i < N; i++) {
1167                    DbStats dbStats = stats.dbStats.get(i);
1168                    printRow(pw, DB_INFO_FORMAT,
1169                            (dbStats.pageSize > 0) ? String.valueOf(dbStats.pageSize) : " ",
1170                            (dbStats.dbSize > 0) ? String.valueOf(dbStats.dbSize) : " ",
1171                            (dbStats.lookaside > 0) ? String.valueOf(dbStats.lookaside) : " ",
1172                            dbStats.cache, dbStats.dbName);
1173                }
1174            }
1175
1176            // Asset details.
1177            String assetAlloc = AssetManager.getAssetAllocations();
1178            if (assetAlloc != null) {
1179                pw.println(" ");
1180                pw.println(" Asset Allocations");
1181                pw.print(assetAlloc);
1182            }
1183
1184            // Unreachable native memory
1185            if (dumpUnreachable) {
1186                boolean showContents = ((mBoundApplication != null)
1187                    && ((mBoundApplication.appInfo.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0))
1188                    || android.os.Build.IS_DEBUGGABLE;
1189                pw.println(" ");
1190                pw.println(" Unreachable memory");
1191                pw.print(Debug.getUnreachableMemory(100, showContents));
1192            }
1193        }
1194
1195        @Override
1196        public void dumpGfxInfo(ParcelFileDescriptor pfd, String[] args) {
1197            nDumpGraphicsInfo(pfd.getFileDescriptor());
1198            WindowManagerGlobal.getInstance().dumpGfxInfo(pfd.getFileDescriptor(), args);
1199            IoUtils.closeQuietly(pfd);
1200        }
1201
1202        private void dumpDatabaseInfo(ParcelFileDescriptor pfd, String[] args) {
1203            PrintWriter pw = new FastPrintWriter(
1204                    new FileOutputStream(pfd.getFileDescriptor()));
1205            PrintWriterPrinter printer = new PrintWriterPrinter(pw);
1206            SQLiteDebug.dump(printer, args);
1207            pw.flush();
1208        }
1209
1210        @Override
1211        public void dumpDbInfo(final ParcelFileDescriptor pfd, final String[] args) {
1212            if (mSystemThread) {
1213                // Ensure this invocation is asynchronous to prevent writer waiting if buffer cannot
1214                // be consumed. But it must duplicate the file descriptor first, since caller might
1215                // be closing it.
1216                final ParcelFileDescriptor dup;
1217                try {
1218                    dup = pfd.dup();
1219                } catch (IOException e) {
1220                    Log.w(TAG, "Could not dup FD " + pfd.getFileDescriptor().getInt$());
1221                    return;
1222                } finally {
1223                    IoUtils.closeQuietly(pfd);
1224                }
1225
1226                AsyncTask.THREAD_POOL_EXECUTOR.execute(new Runnable() {
1227                    @Override
1228                    public void run() {
1229                        try {
1230                            dumpDatabaseInfo(dup, args);
1231                        } finally {
1232                            IoUtils.closeQuietly(dup);
1233                        }
1234                    }
1235                });
1236            } else {
1237                dumpDatabaseInfo(pfd, args);
1238                IoUtils.closeQuietly(pfd);
1239            }
1240        }
1241
1242        @Override
1243        public void unstableProviderDied(IBinder provider) {
1244            sendMessage(H.UNSTABLE_PROVIDER_DIED, provider);
1245        }
1246
1247        @Override
1248        public void requestAssistContextExtras(IBinder activityToken, IBinder requestToken,
1249                int requestType, int sessionId, int flags) {
1250            RequestAssistContextExtras cmd = new RequestAssistContextExtras();
1251            cmd.activityToken = activityToken;
1252            cmd.requestToken = requestToken;
1253            cmd.requestType = requestType;
1254            cmd.sessionId = sessionId;
1255            cmd.flags = flags;
1256            sendMessage(H.REQUEST_ASSIST_CONTEXT_EXTRAS, cmd);
1257        }
1258
1259        public void setCoreSettings(Bundle coreSettings) {
1260            sendMessage(H.SET_CORE_SETTINGS, coreSettings);
1261        }
1262
1263        public void updatePackageCompatibilityInfo(String pkg, CompatibilityInfo info) {
1264            UpdateCompatibilityData ucd = new UpdateCompatibilityData();
1265            ucd.pkg = pkg;
1266            ucd.info = info;
1267            sendMessage(H.UPDATE_PACKAGE_COMPATIBILITY_INFO, ucd);
1268        }
1269
1270        public void scheduleTrimMemory(int level) {
1271            sendMessage(H.TRIM_MEMORY, null, level);
1272        }
1273
1274        public void scheduleTranslucentConversionComplete(IBinder token, boolean drawComplete) {
1275            sendMessage(H.TRANSLUCENT_CONVERSION_COMPLETE, token, drawComplete ? 1 : 0);
1276        }
1277
1278        public void scheduleOnNewActivityOptions(IBinder token, Bundle options) {
1279            sendMessage(H.ON_NEW_ACTIVITY_OPTIONS,
1280                    new Pair<IBinder, ActivityOptions>(token, ActivityOptions.fromBundle(options)));
1281        }
1282
1283        public void setProcessState(int state) {
1284            updateProcessState(state, true);
1285        }
1286
1287        public void updateProcessState(int processState, boolean fromIpc) {
1288            synchronized (this) {
1289                if (mLastProcessState != processState) {
1290                    mLastProcessState = processState;
1291                    // Update Dalvik state based on ActivityManager.PROCESS_STATE_* constants.
1292                    final int DALVIK_PROCESS_STATE_JANK_PERCEPTIBLE = 0;
1293                    final int DALVIK_PROCESS_STATE_JANK_IMPERCEPTIBLE = 1;
1294                    int dalvikProcessState = DALVIK_PROCESS_STATE_JANK_IMPERCEPTIBLE;
1295                    // TODO: Tune this since things like gmail sync are important background but not jank perceptible.
1296                    if (processState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
1297                        dalvikProcessState = DALVIK_PROCESS_STATE_JANK_PERCEPTIBLE;
1298                    }
1299                    VMRuntime.getRuntime().updateProcessState(dalvikProcessState);
1300                    if (false) {
1301                        Slog.i(TAG, "******************* PROCESS STATE CHANGED TO: " + processState
1302                                + (fromIpc ? " (from ipc": ""));
1303                    }
1304                }
1305            }
1306        }
1307
1308        @Override
1309        public void scheduleInstallProvider(ProviderInfo provider) {
1310            sendMessage(H.INSTALL_PROVIDER, provider);
1311        }
1312
1313        @Override
1314        public final void updateTimePrefs(int timeFormatPreference) {
1315            final Boolean timeFormatPreferenceBool;
1316            // For convenience we are using the Intent extra values.
1317            if (timeFormatPreference == Intent.EXTRA_TIME_PREF_VALUE_USE_12_HOUR) {
1318                timeFormatPreferenceBool = Boolean.FALSE;
1319            } else if (timeFormatPreference == Intent.EXTRA_TIME_PREF_VALUE_USE_24_HOUR) {
1320                timeFormatPreferenceBool = Boolean.TRUE;
1321            } else {
1322                // timeFormatPreference == Intent.EXTRA_TIME_PREF_VALUE_USE_LOCALE_DEFAULT
1323                // (or unknown).
1324                timeFormatPreferenceBool = null;
1325            }
1326            DateFormat.set24HourTimePref(timeFormatPreferenceBool);
1327        }
1328
1329        @Override
1330        public void scheduleCancelVisibleBehind(IBinder token) {
1331            sendMessage(H.CANCEL_VISIBLE_BEHIND, token);
1332        }
1333
1334        @Override
1335        public void scheduleBackgroundVisibleBehindChanged(IBinder token, boolean visible) {
1336            sendMessage(H.BACKGROUND_VISIBLE_BEHIND_CHANGED, token, visible ? 1 : 0);
1337        }
1338
1339        @Override
1340        public void scheduleEnterAnimationComplete(IBinder token) {
1341            sendMessage(H.ENTER_ANIMATION_COMPLETE, token);
1342        }
1343
1344        @Override
1345        public void notifyCleartextNetwork(byte[] firstPacket) {
1346            if (StrictMode.vmCleartextNetworkEnabled()) {
1347                StrictMode.onCleartextNetworkDetected(firstPacket);
1348            }
1349        }
1350
1351        @Override
1352        public void startBinderTracking() {
1353            sendMessage(H.START_BINDER_TRACKING, null);
1354        }
1355
1356        @Override
1357        public void stopBinderTrackingAndDump(ParcelFileDescriptor pfd) {
1358            try {
1359                sendMessage(H.STOP_BINDER_TRACKING_AND_DUMP, pfd.dup());
1360            } catch (IOException e) {
1361            } finally {
1362                IoUtils.closeQuietly(pfd);
1363            }
1364        }
1365
1366        @Override
1367        public void scheduleMultiWindowModeChanged(IBinder token, boolean isInMultiWindowMode)
1368                throws RemoteException {
1369            sendMessage(H.MULTI_WINDOW_MODE_CHANGED, token, isInMultiWindowMode ? 1 : 0);
1370        }
1371
1372        @Override
1373        public void schedulePictureInPictureModeChanged(IBinder token, boolean isInPipMode)
1374                throws RemoteException {
1375            sendMessage(H.PICTURE_IN_PICTURE_MODE_CHANGED, token, isInPipMode ? 1 : 0);
1376        }
1377
1378        @Override
1379        public void scheduleLocalVoiceInteractionStarted(IBinder token,
1380                IVoiceInteractor voiceInteractor) throws RemoteException {
1381            SomeArgs args = SomeArgs.obtain();
1382            args.arg1 = token;
1383            args.arg2 = voiceInteractor;
1384            sendMessage(H.LOCAL_VOICE_INTERACTION_STARTED, args);
1385        }
1386
1387        @Override
1388        public void handleTrustStorageUpdate() {
1389            NetworkSecurityPolicy.getInstance().handleTrustStorageUpdate();
1390        }
1391    }
1392
1393    private int getLifecycleSeq() {
1394        synchronized (mResourcesManager) {
1395            return mLifecycleSeq++;
1396        }
1397    }
1398
1399    private class H extends Handler {
1400        public static final int LAUNCH_ACTIVITY         = 100;
1401        public static final int PAUSE_ACTIVITY          = 101;
1402        public static final int PAUSE_ACTIVITY_FINISHING= 102;
1403        public static final int STOP_ACTIVITY_SHOW      = 103;
1404        public static final int STOP_ACTIVITY_HIDE      = 104;
1405        public static final int SHOW_WINDOW             = 105;
1406        public static final int HIDE_WINDOW             = 106;
1407        public static final int RESUME_ACTIVITY         = 107;
1408        public static final int SEND_RESULT             = 108;
1409        public static final int DESTROY_ACTIVITY        = 109;
1410        public static final int BIND_APPLICATION        = 110;
1411        public static final int EXIT_APPLICATION        = 111;
1412        public static final int NEW_INTENT              = 112;
1413        public static final int RECEIVER                = 113;
1414        public static final int CREATE_SERVICE          = 114;
1415        public static final int SERVICE_ARGS            = 115;
1416        public static final int STOP_SERVICE            = 116;
1417
1418        public static final int CONFIGURATION_CHANGED   = 118;
1419        public static final int CLEAN_UP_CONTEXT        = 119;
1420        public static final int GC_WHEN_IDLE            = 120;
1421        public static final int BIND_SERVICE            = 121;
1422        public static final int UNBIND_SERVICE          = 122;
1423        public static final int DUMP_SERVICE            = 123;
1424        public static final int LOW_MEMORY              = 124;
1425        public static final int ACTIVITY_CONFIGURATION_CHANGED = 125;
1426        public static final int RELAUNCH_ACTIVITY       = 126;
1427        public static final int PROFILER_CONTROL        = 127;
1428        public static final int CREATE_BACKUP_AGENT     = 128;
1429        public static final int DESTROY_BACKUP_AGENT    = 129;
1430        public static final int SUICIDE                 = 130;
1431        public static final int REMOVE_PROVIDER         = 131;
1432        public static final int ENABLE_JIT              = 132;
1433        public static final int DISPATCH_PACKAGE_BROADCAST = 133;
1434        public static final int SCHEDULE_CRASH          = 134;
1435        public static final int DUMP_HEAP               = 135;
1436        public static final int DUMP_ACTIVITY           = 136;
1437        public static final int SLEEPING                = 137;
1438        public static final int SET_CORE_SETTINGS       = 138;
1439        public static final int UPDATE_PACKAGE_COMPATIBILITY_INFO = 139;
1440        public static final int TRIM_MEMORY             = 140;
1441        public static final int DUMP_PROVIDER           = 141;
1442        public static final int UNSTABLE_PROVIDER_DIED  = 142;
1443        public static final int REQUEST_ASSIST_CONTEXT_EXTRAS = 143;
1444        public static final int TRANSLUCENT_CONVERSION_COMPLETE = 144;
1445        public static final int INSTALL_PROVIDER        = 145;
1446        public static final int ON_NEW_ACTIVITY_OPTIONS = 146;
1447        public static final int CANCEL_VISIBLE_BEHIND = 147;
1448        public static final int BACKGROUND_VISIBLE_BEHIND_CHANGED = 148;
1449        public static final int ENTER_ANIMATION_COMPLETE = 149;
1450        public static final int START_BINDER_TRACKING = 150;
1451        public static final int STOP_BINDER_TRACKING_AND_DUMP = 151;
1452        public static final int MULTI_WINDOW_MODE_CHANGED = 152;
1453        public static final int PICTURE_IN_PICTURE_MODE_CHANGED = 153;
1454        public static final int LOCAL_VOICE_INTERACTION_STARTED = 154;
1455        public static final int ATTACH_AGENT = 155;
1456        public static final int APPLICATION_INFO_CHANGED = 156;
1457
1458        String codeToString(int code) {
1459            if (DEBUG_MESSAGES) {
1460                switch (code) {
1461                    case LAUNCH_ACTIVITY: return "LAUNCH_ACTIVITY";
1462                    case PAUSE_ACTIVITY: return "PAUSE_ACTIVITY";
1463                    case PAUSE_ACTIVITY_FINISHING: return "PAUSE_ACTIVITY_FINISHING";
1464                    case STOP_ACTIVITY_SHOW: return "STOP_ACTIVITY_SHOW";
1465                    case STOP_ACTIVITY_HIDE: return "STOP_ACTIVITY_HIDE";
1466                    case SHOW_WINDOW: return "SHOW_WINDOW";
1467                    case HIDE_WINDOW: return "HIDE_WINDOW";
1468                    case RESUME_ACTIVITY: return "RESUME_ACTIVITY";
1469                    case SEND_RESULT: return "SEND_RESULT";
1470                    case DESTROY_ACTIVITY: return "DESTROY_ACTIVITY";
1471                    case BIND_APPLICATION: return "BIND_APPLICATION";
1472                    case EXIT_APPLICATION: return "EXIT_APPLICATION";
1473                    case NEW_INTENT: return "NEW_INTENT";
1474                    case RECEIVER: return "RECEIVER";
1475                    case CREATE_SERVICE: return "CREATE_SERVICE";
1476                    case SERVICE_ARGS: return "SERVICE_ARGS";
1477                    case STOP_SERVICE: return "STOP_SERVICE";
1478                    case CONFIGURATION_CHANGED: return "CONFIGURATION_CHANGED";
1479                    case CLEAN_UP_CONTEXT: return "CLEAN_UP_CONTEXT";
1480                    case GC_WHEN_IDLE: return "GC_WHEN_IDLE";
1481                    case BIND_SERVICE: return "BIND_SERVICE";
1482                    case UNBIND_SERVICE: return "UNBIND_SERVICE";
1483                    case DUMP_SERVICE: return "DUMP_SERVICE";
1484                    case LOW_MEMORY: return "LOW_MEMORY";
1485                    case ACTIVITY_CONFIGURATION_CHANGED: return "ACTIVITY_CONFIGURATION_CHANGED";
1486                    case RELAUNCH_ACTIVITY: return "RELAUNCH_ACTIVITY";
1487                    case PROFILER_CONTROL: return "PROFILER_CONTROL";
1488                    case CREATE_BACKUP_AGENT: return "CREATE_BACKUP_AGENT";
1489                    case DESTROY_BACKUP_AGENT: return "DESTROY_BACKUP_AGENT";
1490                    case SUICIDE: return "SUICIDE";
1491                    case REMOVE_PROVIDER: return "REMOVE_PROVIDER";
1492                    case ENABLE_JIT: return "ENABLE_JIT";
1493                    case DISPATCH_PACKAGE_BROADCAST: return "DISPATCH_PACKAGE_BROADCAST";
1494                    case SCHEDULE_CRASH: return "SCHEDULE_CRASH";
1495                    case DUMP_HEAP: return "DUMP_HEAP";
1496                    case DUMP_ACTIVITY: return "DUMP_ACTIVITY";
1497                    case SLEEPING: return "SLEEPING";
1498                    case SET_CORE_SETTINGS: return "SET_CORE_SETTINGS";
1499                    case UPDATE_PACKAGE_COMPATIBILITY_INFO: return "UPDATE_PACKAGE_COMPATIBILITY_INFO";
1500                    case TRIM_MEMORY: return "TRIM_MEMORY";
1501                    case DUMP_PROVIDER: return "DUMP_PROVIDER";
1502                    case UNSTABLE_PROVIDER_DIED: return "UNSTABLE_PROVIDER_DIED";
1503                    case REQUEST_ASSIST_CONTEXT_EXTRAS: return "REQUEST_ASSIST_CONTEXT_EXTRAS";
1504                    case TRANSLUCENT_CONVERSION_COMPLETE: return "TRANSLUCENT_CONVERSION_COMPLETE";
1505                    case INSTALL_PROVIDER: return "INSTALL_PROVIDER";
1506                    case ON_NEW_ACTIVITY_OPTIONS: return "ON_NEW_ACTIVITY_OPTIONS";
1507                    case CANCEL_VISIBLE_BEHIND: return "CANCEL_VISIBLE_BEHIND";
1508                    case BACKGROUND_VISIBLE_BEHIND_CHANGED: return "BACKGROUND_VISIBLE_BEHIND_CHANGED";
1509                    case ENTER_ANIMATION_COMPLETE: return "ENTER_ANIMATION_COMPLETE";
1510                    case MULTI_WINDOW_MODE_CHANGED: return "MULTI_WINDOW_MODE_CHANGED";
1511                    case PICTURE_IN_PICTURE_MODE_CHANGED: return "PICTURE_IN_PICTURE_MODE_CHANGED";
1512                    case LOCAL_VOICE_INTERACTION_STARTED: return "LOCAL_VOICE_INTERACTION_STARTED";
1513                    case ATTACH_AGENT: return "ATTACH_AGENT";
1514                    case APPLICATION_INFO_CHANGED: return "APPLICATION_INFO_CHANGED";
1515                }
1516            }
1517            return Integer.toString(code);
1518        }
1519        public void handleMessage(Message msg) {
1520            if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
1521            switch (msg.what) {
1522                case LAUNCH_ACTIVITY: {
1523                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
1524                    final ActivityClientRecord r = (ActivityClientRecord) msg.obj;
1525
1526                    r.packageInfo = getPackageInfoNoCheck(
1527                            r.activityInfo.applicationInfo, r.compatInfo);
1528                    handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");
1529                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1530                } break;
1531                case RELAUNCH_ACTIVITY: {
1532                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityRestart");
1533                    ActivityClientRecord r = (ActivityClientRecord)msg.obj;
1534                    handleRelaunchActivity(r);
1535                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1536                } break;
1537                case PAUSE_ACTIVITY: {
1538                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
1539                    SomeArgs args = (SomeArgs) msg.obj;
1540                    handlePauseActivity((IBinder) args.arg1, false,
1541                            (args.argi1 & USER_LEAVING) != 0, args.argi2,
1542                            (args.argi1 & DONT_REPORT) != 0, args.argi3);
1543                    maybeSnapshot();
1544                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1545                } break;
1546                case PAUSE_ACTIVITY_FINISHING: {
1547                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
1548                    SomeArgs args = (SomeArgs) msg.obj;
1549                    handlePauseActivity((IBinder) args.arg1, true, (args.argi1 & USER_LEAVING) != 0,
1550                            args.argi2, (args.argi1 & DONT_REPORT) != 0, args.argi3);
1551                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1552                } break;
1553                case STOP_ACTIVITY_SHOW: {
1554                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStop");
1555                    SomeArgs args = (SomeArgs) msg.obj;
1556                    handleStopActivity((IBinder) args.arg1, true, args.argi2, args.argi3);
1557                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1558                } break;
1559                case STOP_ACTIVITY_HIDE: {
1560                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStop");
1561                    SomeArgs args = (SomeArgs) msg.obj;
1562                    handleStopActivity((IBinder) args.arg1, false, args.argi2, args.argi3);
1563                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1564                } break;
1565                case SHOW_WINDOW:
1566                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityShowWindow");
1567                    handleWindowVisibility((IBinder)msg.obj, true);
1568                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1569                    break;
1570                case HIDE_WINDOW:
1571                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityHideWindow");
1572                    handleWindowVisibility((IBinder)msg.obj, false);
1573                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1574                    break;
1575                case RESUME_ACTIVITY:
1576                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityResume");
1577                    SomeArgs args = (SomeArgs) msg.obj;
1578                    handleResumeActivity((IBinder) args.arg1, true, args.argi1 != 0, true,
1579                            args.argi3, "RESUME_ACTIVITY");
1580                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1581                    break;
1582                case SEND_RESULT:
1583                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityDeliverResult");
1584                    handleSendResult((ResultData)msg.obj);
1585                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1586                    break;
1587                case DESTROY_ACTIVITY:
1588                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityDestroy");
1589                    handleDestroyActivity((IBinder)msg.obj, msg.arg1 != 0,
1590                            msg.arg2, false);
1591                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1592                    break;
1593                case BIND_APPLICATION:
1594                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
1595                    AppBindData data = (AppBindData)msg.obj;
1596                    handleBindApplication(data);
1597                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1598                    break;
1599                case EXIT_APPLICATION:
1600                    if (mInitialApplication != null) {
1601                        mInitialApplication.onTerminate();
1602                    }
1603                    Looper.myLooper().quit();
1604                    break;
1605                case NEW_INTENT:
1606                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityNewIntent");
1607                    handleNewIntent((NewIntentData)msg.obj);
1608                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1609                    break;
1610                case RECEIVER:
1611                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "broadcastReceiveComp");
1612                    handleReceiver((ReceiverData)msg.obj);
1613                    maybeSnapshot();
1614                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1615                    break;
1616                case CREATE_SERVICE:
1617                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, ("serviceCreate: " + String.valueOf(msg.obj)));
1618                    handleCreateService((CreateServiceData)msg.obj);
1619                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1620                    break;
1621                case BIND_SERVICE:
1622                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceBind");
1623                    handleBindService((BindServiceData)msg.obj);
1624                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1625                    break;
1626                case UNBIND_SERVICE:
1627                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceUnbind");
1628                    handleUnbindService((BindServiceData)msg.obj);
1629                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1630                    break;
1631                case SERVICE_ARGS:
1632                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, ("serviceStart: " + String.valueOf(msg.obj)));
1633                    handleServiceArgs((ServiceArgsData)msg.obj);
1634                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1635                    break;
1636                case STOP_SERVICE:
1637                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceStop");
1638                    handleStopService((IBinder)msg.obj);
1639                    maybeSnapshot();
1640                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1641                    break;
1642                case CONFIGURATION_CHANGED:
1643                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "configChanged");
1644                    mCurDefaultDisplayDpi = ((Configuration)msg.obj).densityDpi;
1645                    mUpdatingSystemConfig = true;
1646                    try {
1647                        handleConfigurationChanged((Configuration) msg.obj, null);
1648                    } finally {
1649                        mUpdatingSystemConfig = false;
1650                    }
1651                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1652                    break;
1653                case CLEAN_UP_CONTEXT:
1654                    ContextCleanupInfo cci = (ContextCleanupInfo)msg.obj;
1655                    cci.context.performFinalCleanup(cci.who, cci.what);
1656                    break;
1657                case GC_WHEN_IDLE:
1658                    scheduleGcIdler();
1659                    break;
1660                case DUMP_SERVICE:
1661                    handleDumpService((DumpComponentInfo)msg.obj);
1662                    break;
1663                case LOW_MEMORY:
1664                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "lowMemory");
1665                    handleLowMemory();
1666                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1667                    break;
1668                case ACTIVITY_CONFIGURATION_CHANGED:
1669                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityConfigChanged");
1670                    handleActivityConfigurationChanged((ActivityConfigChangeData) msg.obj,
1671                            msg.arg1 == 1 ? REPORT_TO_ACTIVITY : !REPORT_TO_ACTIVITY);
1672                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1673                    break;
1674                case PROFILER_CONTROL:
1675                    handleProfilerControl(msg.arg1 != 0, (ProfilerInfo)msg.obj, msg.arg2);
1676                    break;
1677                case CREATE_BACKUP_AGENT:
1678                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "backupCreateAgent");
1679                    handleCreateBackupAgent((CreateBackupAgentData)msg.obj);
1680                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1681                    break;
1682                case DESTROY_BACKUP_AGENT:
1683                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "backupDestroyAgent");
1684                    handleDestroyBackupAgent((CreateBackupAgentData)msg.obj);
1685                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1686                    break;
1687                case SUICIDE:
1688                    Process.killProcess(Process.myPid());
1689                    break;
1690                case REMOVE_PROVIDER:
1691                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "providerRemove");
1692                    completeRemoveProvider((ProviderRefCount)msg.obj);
1693                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1694                    break;
1695                case ENABLE_JIT:
1696                    ensureJitEnabled();
1697                    break;
1698                case DISPATCH_PACKAGE_BROADCAST:
1699                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "broadcastPackage");
1700                    handleDispatchPackageBroadcast(msg.arg1, (String[])msg.obj);
1701                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1702                    break;
1703                case SCHEDULE_CRASH:
1704                    throw new RemoteServiceException((String)msg.obj);
1705                case DUMP_HEAP:
1706                    handleDumpHeap(msg.arg1 != 0, (DumpHeapData)msg.obj);
1707                    break;
1708                case DUMP_ACTIVITY:
1709                    handleDumpActivity((DumpComponentInfo)msg.obj);
1710                    break;
1711                case DUMP_PROVIDER:
1712                    handleDumpProvider((DumpComponentInfo)msg.obj);
1713                    break;
1714                case SLEEPING:
1715                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "sleeping");
1716                    handleSleeping((IBinder)msg.obj, msg.arg1 != 0);
1717                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1718                    break;
1719                case SET_CORE_SETTINGS:
1720                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "setCoreSettings");
1721                    handleSetCoreSettings((Bundle) msg.obj);
1722                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1723                    break;
1724                case UPDATE_PACKAGE_COMPATIBILITY_INFO:
1725                    handleUpdatePackageCompatibilityInfo((UpdateCompatibilityData)msg.obj);
1726                    break;
1727                case TRIM_MEMORY:
1728                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "trimMemory");
1729                    handleTrimMemory(msg.arg1);
1730                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1731                    break;
1732                case UNSTABLE_PROVIDER_DIED:
1733                    handleUnstableProviderDied((IBinder)msg.obj, false);
1734                    break;
1735                case REQUEST_ASSIST_CONTEXT_EXTRAS:
1736                    handleRequestAssistContextExtras((RequestAssistContextExtras)msg.obj);
1737                    break;
1738                case TRANSLUCENT_CONVERSION_COMPLETE:
1739                    handleTranslucentConversionComplete((IBinder)msg.obj, msg.arg1 == 1);
1740                    break;
1741                case INSTALL_PROVIDER:
1742                    handleInstallProvider((ProviderInfo) msg.obj);
1743                    break;
1744                case ON_NEW_ACTIVITY_OPTIONS:
1745                    Pair<IBinder, ActivityOptions> pair = (Pair<IBinder, ActivityOptions>) msg.obj;
1746                    onNewActivityOptions(pair.first, pair.second);
1747                    break;
1748                case CANCEL_VISIBLE_BEHIND:
1749                    handleCancelVisibleBehind((IBinder) msg.obj);
1750                    break;
1751                case BACKGROUND_VISIBLE_BEHIND_CHANGED:
1752                    handleOnBackgroundVisibleBehindChanged((IBinder) msg.obj, msg.arg1 > 0);
1753                    break;
1754                case ENTER_ANIMATION_COMPLETE:
1755                    handleEnterAnimationComplete((IBinder) msg.obj);
1756                    break;
1757                case START_BINDER_TRACKING:
1758                    handleStartBinderTracking();
1759                    break;
1760                case STOP_BINDER_TRACKING_AND_DUMP:
1761                    handleStopBinderTrackingAndDump((ParcelFileDescriptor) msg.obj);
1762                    break;
1763                case MULTI_WINDOW_MODE_CHANGED:
1764                    handleMultiWindowModeChanged((IBinder) msg.obj, msg.arg1 == 1);
1765                    break;
1766                case PICTURE_IN_PICTURE_MODE_CHANGED:
1767                    handlePictureInPictureModeChanged((IBinder) msg.obj, msg.arg1 == 1);
1768                    break;
1769                case LOCAL_VOICE_INTERACTION_STARTED:
1770                    handleLocalVoiceInteractionStarted((IBinder) ((SomeArgs) msg.obj).arg1,
1771                            (IVoiceInteractor) ((SomeArgs) msg.obj).arg2);
1772                    break;
1773                case ATTACH_AGENT:
1774                    handleAttachAgent((String) msg.obj);
1775                    break;
1776                case APPLICATION_INFO_CHANGED:
1777                    mUpdatingSystemConfig = true;
1778                    try {
1779                        handleApplicationInfoChanged((ApplicationInfo) msg.obj);
1780                    } finally {
1781                        mUpdatingSystemConfig = false;
1782                    }
1783                    break;
1784            }
1785            Object obj = msg.obj;
1786            if (obj instanceof SomeArgs) {
1787                ((SomeArgs) obj).recycle();
1788            }
1789            if (DEBUG_MESSAGES) Slog.v(TAG, "<<< done: " + codeToString(msg.what));
1790        }
1791
1792        private void maybeSnapshot() {
1793            if (mBoundApplication != null && SamplingProfilerIntegration.isEnabled()) {
1794                // convert the *private* ActivityThread.PackageInfo to *public* known
1795                // android.content.pm.PackageInfo
1796                String packageName = mBoundApplication.info.mPackageName;
1797                android.content.pm.PackageInfo packageInfo = null;
1798                try {
1799                    Context context = getSystemContext();
1800                    if(context == null) {
1801                        Log.e(TAG, "cannot get a valid context");
1802                        return;
1803                    }
1804                    PackageManager pm = context.getPackageManager();
1805                    if(pm == null) {
1806                        Log.e(TAG, "cannot get a valid PackageManager");
1807                        return;
1808                    }
1809                    packageInfo = pm.getPackageInfo(
1810                            packageName, PackageManager.GET_ACTIVITIES);
1811                } catch (NameNotFoundException e) {
1812                    Log.e(TAG, "cannot get package info for " + packageName, e);
1813                }
1814                SamplingProfilerIntegration.writeSnapshot(mBoundApplication.processName, packageInfo);
1815            }
1816        }
1817    }
1818
1819    private class Idler implements MessageQueue.IdleHandler {
1820        @Override
1821        public final boolean queueIdle() {
1822            ActivityClientRecord a = mNewActivities;
1823            boolean stopProfiling = false;
1824            if (mBoundApplication != null && mProfiler.profileFd != null
1825                    && mProfiler.autoStopProfiler) {
1826                stopProfiling = true;
1827            }
1828            if (a != null) {
1829                mNewActivities = null;
1830                IActivityManager am = ActivityManager.getService();
1831                ActivityClientRecord prev;
1832                do {
1833                    if (localLOGV) Slog.v(
1834                        TAG, "Reporting idle of " + a +
1835                        " finished=" +
1836                        (a.activity != null && a.activity.mFinished));
1837                    if (a.activity != null && !a.activity.mFinished) {
1838                        try {
1839                            am.activityIdle(a.token, a.createdConfig, stopProfiling);
1840                            a.createdConfig = null;
1841                        } catch (RemoteException ex) {
1842                            throw ex.rethrowFromSystemServer();
1843                        }
1844                    }
1845                    prev = a;
1846                    a = a.nextIdle;
1847                    prev.nextIdle = null;
1848                } while (a != null);
1849            }
1850            if (stopProfiling) {
1851                mProfiler.stopProfiling();
1852            }
1853            ensureJitEnabled();
1854            return false;
1855        }
1856    }
1857
1858    final class GcIdler implements MessageQueue.IdleHandler {
1859        @Override
1860        public final boolean queueIdle() {
1861            doGcIfNeeded();
1862            return false;
1863        }
1864    }
1865
1866    public static ActivityThread currentActivityThread() {
1867        return sCurrentActivityThread;
1868    }
1869
1870    public static boolean isSystem() {
1871        return (sCurrentActivityThread != null) ? sCurrentActivityThread.mSystemThread : false;
1872    }
1873
1874    public static String currentOpPackageName() {
1875        ActivityThread am = currentActivityThread();
1876        return (am != null && am.getApplication() != null)
1877                ? am.getApplication().getOpPackageName() : null;
1878    }
1879
1880    public static String currentPackageName() {
1881        ActivityThread am = currentActivityThread();
1882        return (am != null && am.mBoundApplication != null)
1883            ? am.mBoundApplication.appInfo.packageName : null;
1884    }
1885
1886    public static String currentProcessName() {
1887        ActivityThread am = currentActivityThread();
1888        return (am != null && am.mBoundApplication != null)
1889            ? am.mBoundApplication.processName : null;
1890    }
1891
1892    public static Application currentApplication() {
1893        ActivityThread am = currentActivityThread();
1894        return am != null ? am.mInitialApplication : null;
1895    }
1896
1897    public static IPackageManager getPackageManager() {
1898        if (sPackageManager != null) {
1899            //Slog.v("PackageManager", "returning cur default = " + sPackageManager);
1900            return sPackageManager;
1901        }
1902        IBinder b = ServiceManager.getService("package");
1903        //Slog.v("PackageManager", "default service binder = " + b);
1904        sPackageManager = IPackageManager.Stub.asInterface(b);
1905        //Slog.v("PackageManager", "default service = " + sPackageManager);
1906        return sPackageManager;
1907    }
1908
1909    private Configuration mMainThreadConfig = new Configuration();
1910
1911    Configuration applyConfigCompatMainThread(int displayDensity, Configuration config,
1912            CompatibilityInfo compat) {
1913        if (config == null) {
1914            return null;
1915        }
1916        if (!compat.supportsScreen()) {
1917            mMainThreadConfig.setTo(config);
1918            config = mMainThreadConfig;
1919            compat.applyToConfiguration(displayDensity, config);
1920        }
1921        return config;
1922    }
1923
1924    /**
1925     * Creates the top level resources for the given package. Will return an existing
1926     * Resources if one has already been created.
1927     */
1928    Resources getTopLevelResources(String resDir, String[] splitResDirs, String[] overlayDirs,
1929            String[] libDirs, int displayId, LoadedApk pkgInfo) {
1930        return mResourcesManager.getResources(null, resDir, splitResDirs, overlayDirs, libDirs,
1931                displayId, null, pkgInfo.getCompatibilityInfo(), pkgInfo.getClassLoader());
1932    }
1933
1934    final Handler getHandler() {
1935        return mH;
1936    }
1937
1938    public final LoadedApk getPackageInfo(String packageName, CompatibilityInfo compatInfo,
1939            int flags) {
1940        return getPackageInfo(packageName, compatInfo, flags, UserHandle.myUserId());
1941    }
1942
1943    public final LoadedApk getPackageInfo(String packageName, CompatibilityInfo compatInfo,
1944            int flags, int userId) {
1945        final boolean differentUser = (UserHandle.myUserId() != userId);
1946        synchronized (mResourcesManager) {
1947            WeakReference<LoadedApk> ref;
1948            if (differentUser) {
1949                // Caching not supported across users
1950                ref = null;
1951            } else if ((flags & Context.CONTEXT_INCLUDE_CODE) != 0) {
1952                ref = mPackages.get(packageName);
1953            } else {
1954                ref = mResourcePackages.get(packageName);
1955            }
1956
1957            LoadedApk packageInfo = ref != null ? ref.get() : null;
1958            //Slog.i(TAG, "getPackageInfo " + packageName + ": " + packageInfo);
1959            //if (packageInfo != null) Slog.i(TAG, "isUptoDate " + packageInfo.mResDir
1960            //        + ": " + packageInfo.mResources.getAssets().isUpToDate());
1961            if (packageInfo != null && (packageInfo.mResources == null
1962                    || packageInfo.mResources.getAssets().isUpToDate())) {
1963                if (packageInfo.isSecurityViolation()
1964                        && (flags&Context.CONTEXT_IGNORE_SECURITY) == 0) {
1965                    throw new SecurityException(
1966                            "Requesting code from " + packageName
1967                            + " to be run in process "
1968                            + mBoundApplication.processName
1969                            + "/" + mBoundApplication.appInfo.uid);
1970                }
1971                return packageInfo;
1972            }
1973        }
1974
1975        ApplicationInfo ai = null;
1976        try {
1977            ai = getPackageManager().getApplicationInfo(packageName,
1978                    PackageManager.GET_SHARED_LIBRARY_FILES
1979                            | PackageManager.MATCH_DEBUG_TRIAGED_MISSING,
1980                    userId);
1981        } catch (RemoteException e) {
1982            throw e.rethrowFromSystemServer();
1983        }
1984
1985        if (ai != null) {
1986            return getPackageInfo(ai, compatInfo, flags);
1987        }
1988
1989        return null;
1990    }
1991
1992    public final LoadedApk getPackageInfo(ApplicationInfo ai, CompatibilityInfo compatInfo,
1993            int flags) {
1994        boolean includeCode = (flags&Context.CONTEXT_INCLUDE_CODE) != 0;
1995        boolean securityViolation = includeCode && ai.uid != 0
1996                && ai.uid != Process.SYSTEM_UID && (mBoundApplication != null
1997                        ? !UserHandle.isSameApp(ai.uid, mBoundApplication.appInfo.uid)
1998                        : true);
1999        boolean registerPackage = includeCode && (flags&Context.CONTEXT_REGISTER_PACKAGE) != 0;
2000        if ((flags&(Context.CONTEXT_INCLUDE_CODE
2001                |Context.CONTEXT_IGNORE_SECURITY))
2002                == Context.CONTEXT_INCLUDE_CODE) {
2003            if (securityViolation) {
2004                String msg = "Requesting code from " + ai.packageName
2005                        + " (with uid " + ai.uid + ")";
2006                if (mBoundApplication != null) {
2007                    msg = msg + " to be run in process "
2008                        + mBoundApplication.processName + " (with uid "
2009                        + mBoundApplication.appInfo.uid + ")";
2010                }
2011                throw new SecurityException(msg);
2012            }
2013        }
2014        return getPackageInfo(ai, compatInfo, null, securityViolation, includeCode,
2015                registerPackage);
2016    }
2017
2018    public final LoadedApk getPackageInfoNoCheck(ApplicationInfo ai,
2019            CompatibilityInfo compatInfo) {
2020        return getPackageInfo(ai, compatInfo, null, false, true, false);
2021    }
2022
2023    public final LoadedApk peekPackageInfo(String packageName, boolean includeCode) {
2024        synchronized (mResourcesManager) {
2025            WeakReference<LoadedApk> ref;
2026            if (includeCode) {
2027                ref = mPackages.get(packageName);
2028            } else {
2029                ref = mResourcePackages.get(packageName);
2030            }
2031            return ref != null ? ref.get() : null;
2032        }
2033    }
2034
2035    private LoadedApk getPackageInfo(ApplicationInfo aInfo, CompatibilityInfo compatInfo,
2036            ClassLoader baseLoader, boolean securityViolation, boolean includeCode,
2037            boolean registerPackage) {
2038        final boolean differentUser = (UserHandle.myUserId() != UserHandle.getUserId(aInfo.uid));
2039        synchronized (mResourcesManager) {
2040            WeakReference<LoadedApk> ref;
2041            if (differentUser) {
2042                // Caching not supported across users
2043                ref = null;
2044            } else if (includeCode) {
2045                ref = mPackages.get(aInfo.packageName);
2046            } else {
2047                ref = mResourcePackages.get(aInfo.packageName);
2048            }
2049
2050            LoadedApk packageInfo = ref != null ? ref.get() : null;
2051            if (packageInfo == null || (packageInfo.mResources != null
2052                    && !packageInfo.mResources.getAssets().isUpToDate())) {
2053                if (localLOGV) Slog.v(TAG, (includeCode ? "Loading code package "
2054                        : "Loading resource-only package ") + aInfo.packageName
2055                        + " (in " + (mBoundApplication != null
2056                                ? mBoundApplication.processName : null)
2057                        + ")");
2058                packageInfo =
2059                    new LoadedApk(this, aInfo, compatInfo, baseLoader,
2060                            securityViolation, includeCode &&
2061                            (aInfo.flags&ApplicationInfo.FLAG_HAS_CODE) != 0, registerPackage);
2062
2063                if (mSystemThread && "android".equals(aInfo.packageName)) {
2064                    packageInfo.installSystemApplicationInfo(aInfo,
2065                            getSystemContext().mPackageInfo.getClassLoader());
2066                }
2067
2068                if (differentUser) {
2069                    // Caching not supported across users
2070                } else if (includeCode) {
2071                    mPackages.put(aInfo.packageName,
2072                            new WeakReference<LoadedApk>(packageInfo));
2073                } else {
2074                    mResourcePackages.put(aInfo.packageName,
2075                            new WeakReference<LoadedApk>(packageInfo));
2076                }
2077            }
2078            return packageInfo;
2079        }
2080    }
2081
2082    ActivityThread() {
2083        mResourcesManager = ResourcesManager.getInstance();
2084    }
2085
2086    public ApplicationThread getApplicationThread()
2087    {
2088        return mAppThread;
2089    }
2090
2091    public Instrumentation getInstrumentation()
2092    {
2093        return mInstrumentation;
2094    }
2095
2096    public boolean isProfiling() {
2097        return mProfiler != null && mProfiler.profileFile != null
2098                && mProfiler.profileFd == null;
2099    }
2100
2101    public String getProfileFilePath() {
2102        return mProfiler.profileFile;
2103    }
2104
2105    public Looper getLooper() {
2106        return mLooper;
2107    }
2108
2109    public Application getApplication() {
2110        return mInitialApplication;
2111    }
2112
2113    public String getProcessName() {
2114        return mBoundApplication.processName;
2115    }
2116
2117    public ContextImpl getSystemContext() {
2118        synchronized (this) {
2119            if (mSystemContext == null) {
2120                mSystemContext = ContextImpl.createSystemContext(this);
2121            }
2122            return mSystemContext;
2123        }
2124    }
2125
2126    public void installSystemApplicationInfo(ApplicationInfo info, ClassLoader classLoader) {
2127        synchronized (this) {
2128            getSystemContext().installSystemApplicationInfo(info, classLoader);
2129
2130            // give ourselves a default profiler
2131            mProfiler = new Profiler();
2132        }
2133    }
2134
2135    void ensureJitEnabled() {
2136        if (!mJitEnabled) {
2137            mJitEnabled = true;
2138            dalvik.system.VMRuntime.getRuntime().startJitCompilation();
2139        }
2140    }
2141
2142    void scheduleGcIdler() {
2143        if (!mGcIdlerScheduled) {
2144            mGcIdlerScheduled = true;
2145            Looper.myQueue().addIdleHandler(mGcIdler);
2146        }
2147        mH.removeMessages(H.GC_WHEN_IDLE);
2148    }
2149
2150    void unscheduleGcIdler() {
2151        if (mGcIdlerScheduled) {
2152            mGcIdlerScheduled = false;
2153            Looper.myQueue().removeIdleHandler(mGcIdler);
2154        }
2155        mH.removeMessages(H.GC_WHEN_IDLE);
2156    }
2157
2158    void doGcIfNeeded() {
2159        mGcIdlerScheduled = false;
2160        final long now = SystemClock.uptimeMillis();
2161        //Slog.i(TAG, "**** WE MIGHT WANT TO GC: then=" + Binder.getLastGcTime()
2162        //        + "m now=" + now);
2163        if ((BinderInternal.getLastGcTime()+MIN_TIME_BETWEEN_GCS) < now) {
2164            //Slog.i(TAG, "**** WE DO, WE DO WANT TO GC!");
2165            BinderInternal.forceGc("bg");
2166        }
2167    }
2168
2169    private static final String HEAP_FULL_COLUMN
2170            = "%13s %8s %8s %8s %8s %8s %8s %8s %8s %8s %8s";
2171    private static final String HEAP_COLUMN
2172            = "%13s %8s %8s %8s %8s %8s %8s %8s";
2173    private static final String ONE_COUNT_COLUMN = "%21s %8d";
2174    private static final String TWO_COUNT_COLUMNS = "%21s %8d %21s %8d";
2175    private static final String ONE_COUNT_COLUMN_HEADER = "%21s %8s";
2176
2177    // Formatting for checkin service - update version if row format changes
2178    private static final int ACTIVITY_THREAD_CHECKIN_VERSION = 4;
2179
2180    static void printRow(PrintWriter pw, String format, Object...objs) {
2181        pw.println(String.format(format, objs));
2182    }
2183
2184    public static void dumpMemInfoTable(PrintWriter pw, Debug.MemoryInfo memInfo, boolean checkin,
2185            boolean dumpFullInfo, boolean dumpDalvik, boolean dumpSummaryOnly,
2186            int pid, String processName,
2187            long nativeMax, long nativeAllocated, long nativeFree,
2188            long dalvikMax, long dalvikAllocated, long dalvikFree) {
2189
2190        // For checkin, we print one long comma-separated list of values
2191        if (checkin) {
2192            // NOTE: if you change anything significant below, also consider changing
2193            // ACTIVITY_THREAD_CHECKIN_VERSION.
2194
2195            // Header
2196            pw.print(ACTIVITY_THREAD_CHECKIN_VERSION); pw.print(',');
2197            pw.print(pid); pw.print(',');
2198            pw.print(processName); pw.print(',');
2199
2200            // Heap info - max
2201            pw.print(nativeMax); pw.print(',');
2202            pw.print(dalvikMax); pw.print(',');
2203            pw.print("N/A,");
2204            pw.print(nativeMax + dalvikMax); pw.print(',');
2205
2206            // Heap info - allocated
2207            pw.print(nativeAllocated); pw.print(',');
2208            pw.print(dalvikAllocated); pw.print(',');
2209            pw.print("N/A,");
2210            pw.print(nativeAllocated + dalvikAllocated); pw.print(',');
2211
2212            // Heap info - free
2213            pw.print(nativeFree); pw.print(',');
2214            pw.print(dalvikFree); pw.print(',');
2215            pw.print("N/A,");
2216            pw.print(nativeFree + dalvikFree); pw.print(',');
2217
2218            // Heap info - proportional set size
2219            pw.print(memInfo.nativePss); pw.print(',');
2220            pw.print(memInfo.dalvikPss); pw.print(',');
2221            pw.print(memInfo.otherPss); pw.print(',');
2222            pw.print(memInfo.getTotalPss()); pw.print(',');
2223
2224            // Heap info - swappable set size
2225            pw.print(memInfo.nativeSwappablePss); pw.print(',');
2226            pw.print(memInfo.dalvikSwappablePss); pw.print(',');
2227            pw.print(memInfo.otherSwappablePss); pw.print(',');
2228            pw.print(memInfo.getTotalSwappablePss()); pw.print(',');
2229
2230            // Heap info - shared dirty
2231            pw.print(memInfo.nativeSharedDirty); pw.print(',');
2232            pw.print(memInfo.dalvikSharedDirty); pw.print(',');
2233            pw.print(memInfo.otherSharedDirty); pw.print(',');
2234            pw.print(memInfo.getTotalSharedDirty()); pw.print(',');
2235
2236            // Heap info - shared clean
2237            pw.print(memInfo.nativeSharedClean); pw.print(',');
2238            pw.print(memInfo.dalvikSharedClean); pw.print(',');
2239            pw.print(memInfo.otherSharedClean); pw.print(',');
2240            pw.print(memInfo.getTotalSharedClean()); pw.print(',');
2241
2242            // Heap info - private Dirty
2243            pw.print(memInfo.nativePrivateDirty); pw.print(',');
2244            pw.print(memInfo.dalvikPrivateDirty); pw.print(',');
2245            pw.print(memInfo.otherPrivateDirty); pw.print(',');
2246            pw.print(memInfo.getTotalPrivateDirty()); pw.print(',');
2247
2248            // Heap info - private Clean
2249            pw.print(memInfo.nativePrivateClean); pw.print(',');
2250            pw.print(memInfo.dalvikPrivateClean); pw.print(',');
2251            pw.print(memInfo.otherPrivateClean); pw.print(',');
2252            pw.print(memInfo.getTotalPrivateClean()); pw.print(',');
2253
2254            // Heap info - swapped out
2255            pw.print(memInfo.nativeSwappedOut); pw.print(',');
2256            pw.print(memInfo.dalvikSwappedOut); pw.print(',');
2257            pw.print(memInfo.otherSwappedOut); pw.print(',');
2258            pw.print(memInfo.getTotalSwappedOut()); pw.print(',');
2259
2260            // Heap info - swapped out pss
2261            if (memInfo.hasSwappedOutPss) {
2262                pw.print(memInfo.nativeSwappedOutPss); pw.print(',');
2263                pw.print(memInfo.dalvikSwappedOutPss); pw.print(',');
2264                pw.print(memInfo.otherSwappedOutPss); pw.print(',');
2265                pw.print(memInfo.getTotalSwappedOutPss()); pw.print(',');
2266            } else {
2267                pw.print("N/A,");
2268                pw.print("N/A,");
2269                pw.print("N/A,");
2270                pw.print("N/A,");
2271            }
2272
2273            // Heap info - other areas
2274            for (int i=0; i<Debug.MemoryInfo.NUM_OTHER_STATS; i++) {
2275                pw.print(Debug.MemoryInfo.getOtherLabel(i)); pw.print(',');
2276                pw.print(memInfo.getOtherPss(i)); pw.print(',');
2277                pw.print(memInfo.getOtherSwappablePss(i)); pw.print(',');
2278                pw.print(memInfo.getOtherSharedDirty(i)); pw.print(',');
2279                pw.print(memInfo.getOtherSharedClean(i)); pw.print(',');
2280                pw.print(memInfo.getOtherPrivateDirty(i)); pw.print(',');
2281                pw.print(memInfo.getOtherPrivateClean(i)); pw.print(',');
2282                pw.print(memInfo.getOtherSwappedOut(i)); pw.print(',');
2283                if (memInfo.hasSwappedOutPss) {
2284                    pw.print(memInfo.getOtherSwappedOutPss(i)); pw.print(',');
2285                } else {
2286                    pw.print("N/A,");
2287                }
2288            }
2289            return;
2290        }
2291
2292        if (!dumpSummaryOnly) {
2293            if (dumpFullInfo) {
2294                printRow(pw, HEAP_FULL_COLUMN, "", "Pss", "Pss", "Shared", "Private",
2295                        "Shared", "Private", memInfo.hasSwappedOutPss ? "SwapPss" : "Swap",
2296                        "Heap", "Heap", "Heap");
2297                printRow(pw, HEAP_FULL_COLUMN, "", "Total", "Clean", "Dirty", "Dirty",
2298                        "Clean", "Clean", "Dirty",
2299                        "Size", "Alloc", "Free");
2300                printRow(pw, HEAP_FULL_COLUMN, "", "------", "------", "------", "------",
2301                        "------", "------", "------", "------", "------", "------");
2302                printRow(pw, HEAP_FULL_COLUMN, "Native Heap", memInfo.nativePss,
2303                        memInfo.nativeSwappablePss, memInfo.nativeSharedDirty,
2304                        memInfo.nativePrivateDirty, memInfo.nativeSharedClean,
2305                        memInfo.nativePrivateClean, memInfo.hasSwappedOutPss ?
2306                        memInfo.nativeSwappedOut : memInfo.nativeSwappedOutPss,
2307                        nativeMax, nativeAllocated, nativeFree);
2308                printRow(pw, HEAP_FULL_COLUMN, "Dalvik Heap", memInfo.dalvikPss,
2309                        memInfo.dalvikSwappablePss, memInfo.dalvikSharedDirty,
2310                        memInfo.dalvikPrivateDirty, memInfo.dalvikSharedClean,
2311                        memInfo.dalvikPrivateClean, memInfo.hasSwappedOutPss ?
2312                        memInfo.dalvikSwappedOut : memInfo.dalvikSwappedOutPss,
2313                        dalvikMax, dalvikAllocated, dalvikFree);
2314            } else {
2315                printRow(pw, HEAP_COLUMN, "", "Pss", "Private",
2316                        "Private", memInfo.hasSwappedOutPss ? "SwapPss" : "Swap",
2317                        "Heap", "Heap", "Heap");
2318                printRow(pw, HEAP_COLUMN, "", "Total", "Dirty",
2319                        "Clean", "Dirty", "Size", "Alloc", "Free");
2320                printRow(pw, HEAP_COLUMN, "", "------", "------", "------",
2321                        "------", "------", "------", "------", "------");
2322                printRow(pw, HEAP_COLUMN, "Native Heap", memInfo.nativePss,
2323                        memInfo.nativePrivateDirty,
2324                        memInfo.nativePrivateClean,
2325                        memInfo.hasSwappedOutPss ? memInfo.nativeSwappedOutPss :
2326                        memInfo.nativeSwappedOut,
2327                        nativeMax, nativeAllocated, nativeFree);
2328                printRow(pw, HEAP_COLUMN, "Dalvik Heap", memInfo.dalvikPss,
2329                        memInfo.dalvikPrivateDirty,
2330                        memInfo.dalvikPrivateClean,
2331                        memInfo.hasSwappedOutPss ? memInfo.dalvikSwappedOutPss :
2332                        memInfo.dalvikSwappedOut,
2333                        dalvikMax, dalvikAllocated, dalvikFree);
2334            }
2335
2336            int otherPss = memInfo.otherPss;
2337            int otherSwappablePss = memInfo.otherSwappablePss;
2338            int otherSharedDirty = memInfo.otherSharedDirty;
2339            int otherPrivateDirty = memInfo.otherPrivateDirty;
2340            int otherSharedClean = memInfo.otherSharedClean;
2341            int otherPrivateClean = memInfo.otherPrivateClean;
2342            int otherSwappedOut = memInfo.otherSwappedOut;
2343            int otherSwappedOutPss = memInfo.otherSwappedOutPss;
2344
2345            for (int i=0; i<Debug.MemoryInfo.NUM_OTHER_STATS; i++) {
2346                final int myPss = memInfo.getOtherPss(i);
2347                final int mySwappablePss = memInfo.getOtherSwappablePss(i);
2348                final int mySharedDirty = memInfo.getOtherSharedDirty(i);
2349                final int myPrivateDirty = memInfo.getOtherPrivateDirty(i);
2350                final int mySharedClean = memInfo.getOtherSharedClean(i);
2351                final int myPrivateClean = memInfo.getOtherPrivateClean(i);
2352                final int mySwappedOut = memInfo.getOtherSwappedOut(i);
2353                final int mySwappedOutPss = memInfo.getOtherSwappedOutPss(i);
2354                if (myPss != 0 || mySharedDirty != 0 || myPrivateDirty != 0
2355                        || mySharedClean != 0 || myPrivateClean != 0
2356                        || (memInfo.hasSwappedOutPss ? mySwappedOutPss : mySwappedOut) != 0) {
2357                    if (dumpFullInfo) {
2358                        printRow(pw, HEAP_FULL_COLUMN, Debug.MemoryInfo.getOtherLabel(i),
2359                                myPss, mySwappablePss, mySharedDirty, myPrivateDirty,
2360                                mySharedClean, myPrivateClean,
2361                                memInfo.hasSwappedOutPss ? mySwappedOutPss : mySwappedOut,
2362                                "", "", "");
2363                    } else {
2364                        printRow(pw, HEAP_COLUMN, Debug.MemoryInfo.getOtherLabel(i),
2365                                myPss, myPrivateDirty,
2366                                myPrivateClean,
2367                                memInfo.hasSwappedOutPss ? mySwappedOutPss : mySwappedOut,
2368                                "", "", "");
2369                    }
2370                    otherPss -= myPss;
2371                    otherSwappablePss -= mySwappablePss;
2372                    otherSharedDirty -= mySharedDirty;
2373                    otherPrivateDirty -= myPrivateDirty;
2374                    otherSharedClean -= mySharedClean;
2375                    otherPrivateClean -= myPrivateClean;
2376                    otherSwappedOut -= mySwappedOut;
2377                    otherSwappedOutPss -= mySwappedOutPss;
2378                }
2379            }
2380
2381            if (dumpFullInfo) {
2382                printRow(pw, HEAP_FULL_COLUMN, "Unknown", otherPss, otherSwappablePss,
2383                        otherSharedDirty, otherPrivateDirty, otherSharedClean, otherPrivateClean,
2384                        memInfo.hasSwappedOutPss ? otherSwappedOutPss : otherSwappedOut,
2385                        "", "", "");
2386                printRow(pw, HEAP_FULL_COLUMN, "TOTAL", memInfo.getTotalPss(),
2387                        memInfo.getTotalSwappablePss(),
2388                        memInfo.getTotalSharedDirty(), memInfo.getTotalPrivateDirty(),
2389                        memInfo.getTotalSharedClean(), memInfo.getTotalPrivateClean(),
2390                        memInfo.hasSwappedOutPss ? memInfo.getTotalSwappedOutPss() :
2391                        memInfo.getTotalSwappedOut(),
2392                        nativeMax+dalvikMax, nativeAllocated+dalvikAllocated,
2393                        nativeFree+dalvikFree);
2394            } else {
2395                printRow(pw, HEAP_COLUMN, "Unknown", otherPss,
2396                        otherPrivateDirty, otherPrivateClean,
2397                        memInfo.hasSwappedOutPss ? otherSwappedOutPss : otherSwappedOut,
2398                        "", "", "");
2399                printRow(pw, HEAP_COLUMN, "TOTAL", memInfo.getTotalPss(),
2400                        memInfo.getTotalPrivateDirty(),
2401                        memInfo.getTotalPrivateClean(),
2402                        memInfo.hasSwappedOutPss ? memInfo.getTotalSwappedOutPss() :
2403                        memInfo.getTotalSwappedOut(),
2404                        nativeMax+dalvikMax,
2405                        nativeAllocated+dalvikAllocated, nativeFree+dalvikFree);
2406            }
2407
2408            if (dumpDalvik) {
2409                pw.println(" ");
2410                pw.println(" Dalvik Details");
2411
2412                for (int i=Debug.MemoryInfo.NUM_OTHER_STATS;
2413                     i<Debug.MemoryInfo.NUM_OTHER_STATS + Debug.MemoryInfo.NUM_DVK_STATS; i++) {
2414                    final int myPss = memInfo.getOtherPss(i);
2415                    final int mySwappablePss = memInfo.getOtherSwappablePss(i);
2416                    final int mySharedDirty = memInfo.getOtherSharedDirty(i);
2417                    final int myPrivateDirty = memInfo.getOtherPrivateDirty(i);
2418                    final int mySharedClean = memInfo.getOtherSharedClean(i);
2419                    final int myPrivateClean = memInfo.getOtherPrivateClean(i);
2420                    final int mySwappedOut = memInfo.getOtherSwappedOut(i);
2421                    final int mySwappedOutPss = memInfo.getOtherSwappedOutPss(i);
2422                    if (myPss != 0 || mySharedDirty != 0 || myPrivateDirty != 0
2423                            || mySharedClean != 0 || myPrivateClean != 0
2424                            || (memInfo.hasSwappedOutPss ? mySwappedOutPss : mySwappedOut) != 0) {
2425                        if (dumpFullInfo) {
2426                            printRow(pw, HEAP_FULL_COLUMN, Debug.MemoryInfo.getOtherLabel(i),
2427                                    myPss, mySwappablePss, mySharedDirty, myPrivateDirty,
2428                                    mySharedClean, myPrivateClean,
2429                                    memInfo.hasSwappedOutPss ? mySwappedOutPss : mySwappedOut,
2430                                    "", "", "");
2431                        } else {
2432                            printRow(pw, HEAP_COLUMN, Debug.MemoryInfo.getOtherLabel(i),
2433                                    myPss, myPrivateDirty,
2434                                    myPrivateClean,
2435                                    memInfo.hasSwappedOutPss ? mySwappedOutPss : mySwappedOut,
2436                                    "", "", "");
2437                        }
2438                    }
2439                }
2440            }
2441        }
2442
2443        pw.println(" ");
2444        pw.println(" App Summary");
2445        printRow(pw, ONE_COUNT_COLUMN_HEADER, "", "Pss(KB)");
2446        printRow(pw, ONE_COUNT_COLUMN_HEADER, "", "------");
2447        printRow(pw, ONE_COUNT_COLUMN,
2448            "Java Heap:", memInfo.getSummaryJavaHeap());
2449        printRow(pw, ONE_COUNT_COLUMN,
2450            "Native Heap:", memInfo.getSummaryNativeHeap());
2451        printRow(pw, ONE_COUNT_COLUMN,
2452            "Code:", memInfo.getSummaryCode());
2453        printRow(pw, ONE_COUNT_COLUMN,
2454            "Stack:", memInfo.getSummaryStack());
2455        printRow(pw, ONE_COUNT_COLUMN,
2456            "Graphics:", memInfo.getSummaryGraphics());
2457        printRow(pw, ONE_COUNT_COLUMN,
2458            "Private Other:", memInfo.getSummaryPrivateOther());
2459        printRow(pw, ONE_COUNT_COLUMN,
2460            "System:", memInfo.getSummarySystem());
2461        pw.println(" ");
2462        if (memInfo.hasSwappedOutPss) {
2463            printRow(pw, TWO_COUNT_COLUMNS,
2464                "TOTAL:", memInfo.getSummaryTotalPss(),
2465                "TOTAL SWAP PSS:", memInfo.getSummaryTotalSwapPss());
2466        } else {
2467            printRow(pw, TWO_COUNT_COLUMNS,
2468                "TOTAL:", memInfo.getSummaryTotalPss(),
2469                "TOTAL SWAP (KB):", memInfo.getSummaryTotalSwap());
2470        }
2471    }
2472
2473    public void registerOnActivityPausedListener(Activity activity,
2474            OnActivityPausedListener listener) {
2475        synchronized (mOnPauseListeners) {
2476            ArrayList<OnActivityPausedListener> list = mOnPauseListeners.get(activity);
2477            if (list == null) {
2478                list = new ArrayList<OnActivityPausedListener>();
2479                mOnPauseListeners.put(activity, list);
2480            }
2481            list.add(listener);
2482        }
2483    }
2484
2485    public void unregisterOnActivityPausedListener(Activity activity,
2486            OnActivityPausedListener listener) {
2487        synchronized (mOnPauseListeners) {
2488            ArrayList<OnActivityPausedListener> list = mOnPauseListeners.get(activity);
2489            if (list != null) {
2490                list.remove(listener);
2491            }
2492        }
2493    }
2494
2495    public final ActivityInfo resolveActivityInfo(Intent intent) {
2496        ActivityInfo aInfo = intent.resolveActivityInfo(
2497                mInitialApplication.getPackageManager(), PackageManager.GET_SHARED_LIBRARY_FILES);
2498        if (aInfo == null) {
2499            // Throw an exception.
2500            Instrumentation.checkStartActivityResult(
2501                    ActivityManager.START_CLASS_NOT_FOUND, intent);
2502        }
2503        return aInfo;
2504    }
2505
2506    public final Activity startActivityNow(Activity parent, String id,
2507        Intent intent, ActivityInfo activityInfo, IBinder token, Bundle state,
2508        Activity.NonConfigurationInstances lastNonConfigurationInstances) {
2509        ActivityClientRecord r = new ActivityClientRecord();
2510            r.token = token;
2511            r.ident = 0;
2512            r.intent = intent;
2513            r.state = state;
2514            r.parent = parent;
2515            r.embeddedID = id;
2516            r.activityInfo = activityInfo;
2517            r.lastNonConfigurationInstances = lastNonConfigurationInstances;
2518        if (localLOGV) {
2519            ComponentName compname = intent.getComponent();
2520            String name;
2521            if (compname != null) {
2522                name = compname.toShortString();
2523            } else {
2524                name = "(Intent " + intent + ").getComponent() returned null";
2525            }
2526            Slog.v(TAG, "Performing launch: action=" + intent.getAction()
2527                    + ", comp=" + name
2528                    + ", token=" + token);
2529        }
2530        return performLaunchActivity(r, null);
2531    }
2532
2533    public final Activity getActivity(IBinder token) {
2534        return mActivities.get(token).activity;
2535    }
2536
2537    public final void sendActivityResult(
2538            IBinder token, String id, int requestCode,
2539            int resultCode, Intent data) {
2540        if (DEBUG_RESULTS) Slog.v(TAG, "sendActivityResult: id=" + id
2541                + " req=" + requestCode + " res=" + resultCode + " data=" + data);
2542        ArrayList<ResultInfo> list = new ArrayList<ResultInfo>();
2543        list.add(new ResultInfo(id, requestCode, resultCode, data));
2544        mAppThread.scheduleSendResult(token, list);
2545    }
2546
2547    private void sendMessage(int what, Object obj) {
2548        sendMessage(what, obj, 0, 0, false);
2549    }
2550
2551    private void sendMessage(int what, Object obj, int arg1) {
2552        sendMessage(what, obj, arg1, 0, false);
2553    }
2554
2555    private void sendMessage(int what, Object obj, int arg1, int arg2) {
2556        sendMessage(what, obj, arg1, arg2, false);
2557    }
2558
2559    private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
2560        if (DEBUG_MESSAGES) Slog.v(
2561            TAG, "SCHEDULE " + what + " " + mH.codeToString(what)
2562            + ": " + arg1 + " / " + obj);
2563        Message msg = Message.obtain();
2564        msg.what = what;
2565        msg.obj = obj;
2566        msg.arg1 = arg1;
2567        msg.arg2 = arg2;
2568        if (async) {
2569            msg.setAsynchronous(true);
2570        }
2571        mH.sendMessage(msg);
2572    }
2573
2574    private void sendMessage(int what, Object obj, int arg1, int arg2, int seq) {
2575        if (DEBUG_MESSAGES) Slog.v(
2576                TAG, "SCHEDULE " + mH.codeToString(what) + " arg1=" + arg1 + " arg2=" + arg2 +
2577                        "seq= " + seq);
2578        Message msg = Message.obtain();
2579        msg.what = what;
2580        SomeArgs args = SomeArgs.obtain();
2581        args.arg1 = obj;
2582        args.argi1 = arg1;
2583        args.argi2 = arg2;
2584        args.argi3 = seq;
2585        msg.obj = args;
2586        mH.sendMessage(msg);
2587    }
2588
2589    final void scheduleContextCleanup(ContextImpl context, String who,
2590            String what) {
2591        ContextCleanupInfo cci = new ContextCleanupInfo();
2592        cci.context = context;
2593        cci.who = who;
2594        cci.what = what;
2595        sendMessage(H.CLEAN_UP_CONTEXT, cci);
2596    }
2597
2598    private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
2599        // System.out.println("##### [" + System.currentTimeMillis() + "] ActivityThread.performLaunchActivity(" + r + ")");
2600
2601        ActivityInfo aInfo = r.activityInfo;
2602        if (r.packageInfo == null) {
2603            r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
2604                    Context.CONTEXT_INCLUDE_CODE);
2605        }
2606
2607        ComponentName component = r.intent.getComponent();
2608        if (component == null) {
2609            component = r.intent.resolveActivity(
2610                mInitialApplication.getPackageManager());
2611            r.intent.setComponent(component);
2612        }
2613
2614        if (r.activityInfo.targetActivity != null) {
2615            component = new ComponentName(r.activityInfo.packageName,
2616                    r.activityInfo.targetActivity);
2617        }
2618
2619        Activity activity = null;
2620        try {
2621            java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
2622            activity = mInstrumentation.newActivity(
2623                    cl, component.getClassName(), r.intent);
2624            StrictMode.incrementExpectedActivityCount(activity.getClass());
2625            r.intent.setExtrasClassLoader(cl);
2626            r.intent.prepareToEnterProcess();
2627            if (r.state != null) {
2628                r.state.setClassLoader(cl);
2629            }
2630        } catch (Exception e) {
2631            if (!mInstrumentation.onException(activity, e)) {
2632                throw new RuntimeException(
2633                    "Unable to instantiate activity " + component
2634                    + ": " + e.toString(), e);
2635            }
2636        }
2637
2638        try {
2639            Application app = r.packageInfo.makeApplication(false, mInstrumentation);
2640
2641            if (localLOGV) Slog.v(TAG, "Performing launch of " + r);
2642            if (localLOGV) Slog.v(
2643                    TAG, r + ": app=" + app
2644                    + ", appName=" + app.getPackageName()
2645                    + ", pkg=" + r.packageInfo.getPackageName()
2646                    + ", comp=" + r.intent.getComponent().toShortString()
2647                    + ", dir=" + r.packageInfo.getAppDir());
2648
2649            if (activity != null) {
2650                Context appContext = createBaseContextForActivity(r, activity);
2651                CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
2652                Configuration config = new Configuration(mCompatConfiguration);
2653                if (r.overrideConfig != null) {
2654                    config.updateFrom(r.overrideConfig);
2655                }
2656                if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "
2657                        + r.activityInfo.name + " with config " + config);
2658                Window window = null;
2659                if (r.mPendingRemoveWindow != null && r.mPreserveWindow) {
2660                    window = r.mPendingRemoveWindow;
2661                    r.mPendingRemoveWindow = null;
2662                    r.mPendingRemoveWindowManager = null;
2663                }
2664                activity.attach(appContext, this, getInstrumentation(), r.token,
2665                        r.ident, app, r.intent, r.activityInfo, title, r.parent,
2666                        r.embeddedID, r.lastNonConfigurationInstances, config,
2667                        r.referrer, r.voiceInteractor, window);
2668
2669                if (customIntent != null) {
2670                    activity.mIntent = customIntent;
2671                }
2672                r.lastNonConfigurationInstances = null;
2673                activity.mStartedActivity = false;
2674                int theme = r.activityInfo.getThemeResource();
2675                if (theme != 0) {
2676                    activity.setTheme(theme);
2677                }
2678
2679                activity.mCalled = false;
2680                if (r.isPersistable()) {
2681                    mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
2682                } else {
2683                    mInstrumentation.callActivityOnCreate(activity, r.state);
2684                }
2685                if (!activity.mCalled) {
2686                    throw new SuperNotCalledException(
2687                        "Activity " + r.intent.getComponent().toShortString() +
2688                        " did not call through to super.onCreate()");
2689                }
2690                r.activity = activity;
2691                r.stopped = true;
2692                if (!r.activity.mFinished) {
2693                    activity.performStart();
2694                    r.stopped = false;
2695                }
2696                if (!r.activity.mFinished) {
2697                    if (r.isPersistable()) {
2698                        if (r.state != null || r.persistentState != null) {
2699                            mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state,
2700                                    r.persistentState);
2701                        }
2702                    } else if (r.state != null) {
2703                        mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
2704                    }
2705                }
2706                if (!r.activity.mFinished) {
2707                    activity.mCalled = false;
2708                    if (r.isPersistable()) {
2709                        mInstrumentation.callActivityOnPostCreate(activity, r.state,
2710                                r.persistentState);
2711                    } else {
2712                        mInstrumentation.callActivityOnPostCreate(activity, r.state);
2713                    }
2714                    if (!activity.mCalled) {
2715                        throw new SuperNotCalledException(
2716                            "Activity " + r.intent.getComponent().toShortString() +
2717                            " did not call through to super.onPostCreate()");
2718                    }
2719                }
2720            }
2721            r.paused = true;
2722
2723            mActivities.put(r.token, r);
2724
2725        } catch (SuperNotCalledException e) {
2726            throw e;
2727
2728        } catch (Exception e) {
2729            if (!mInstrumentation.onException(activity, e)) {
2730                throw new RuntimeException(
2731                    "Unable to start activity " + component
2732                    + ": " + e.toString(), e);
2733            }
2734        }
2735
2736        return activity;
2737    }
2738
2739    private Context createBaseContextForActivity(ActivityClientRecord r, final Activity activity) {
2740        int displayId = Display.DEFAULT_DISPLAY;
2741        try {
2742            displayId = ActivityManager.getService().getActivityDisplayId(r.token);
2743        } catch (RemoteException e) {
2744            throw e.rethrowFromSystemServer();
2745        }
2746
2747        ContextImpl appContext = ContextImpl.createActivityContext(
2748                this, r.packageInfo, r.token, displayId, r.overrideConfig);
2749        appContext.setOuterContext(activity);
2750        Context baseContext = appContext;
2751
2752        final DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance();
2753        // For debugging purposes, if the activity's package name contains the value of
2754        // the "debug.use-second-display" system property as a substring, then show
2755        // its content on a secondary display if there is one.
2756        String pkgName = SystemProperties.get("debug.second-display.pkg");
2757        if (pkgName != null && !pkgName.isEmpty()
2758                && r.packageInfo.mPackageName.contains(pkgName)) {
2759            for (int id : dm.getDisplayIds()) {
2760                if (id != Display.DEFAULT_DISPLAY) {
2761                    Display display =
2762                            dm.getCompatibleDisplay(id, appContext.getDisplayAdjustments(id));
2763                    baseContext = appContext.createDisplayContext(display);
2764                    break;
2765                }
2766            }
2767        }
2768        return baseContext;
2769    }
2770
2771    private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
2772        // If we are getting ready to gc after going to the background, well
2773        // we are back active so skip it.
2774        unscheduleGcIdler();
2775        mSomeActivitiesChanged = true;
2776
2777        if (r.profilerInfo != null) {
2778            mProfiler.setProfiler(r.profilerInfo);
2779            mProfiler.startProfiling();
2780        }
2781
2782        // Make sure we are running with the most recent config.
2783        handleConfigurationChanged(null, null);
2784
2785        if (localLOGV) Slog.v(
2786            TAG, "Handling launch of " + r);
2787
2788        // Initialize before creating the activity
2789        WindowManagerGlobal.initialize();
2790
2791        Activity a = performLaunchActivity(r, customIntent);
2792
2793        if (a != null) {
2794            r.createdConfig = new Configuration(mConfiguration);
2795            reportSizeConfigurations(r);
2796            Bundle oldState = r.state;
2797            handleResumeActivity(r.token, false, r.isForward,
2798                    !r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);
2799
2800            if (!r.activity.mFinished && r.startsNotResumed) {
2801                // The activity manager actually wants this one to start out paused, because it
2802                // needs to be visible but isn't in the foreground. We accomplish this by going
2803                // through the normal startup (because activities expect to go through onResume()
2804                // the first time they run, before their window is displayed), and then pausing it.
2805                // However, in this case we do -not- need to do the full pause cycle (of freezing
2806                // and such) because the activity manager assumes it can just retain the current
2807                // state it has.
2808                performPauseActivityIfNeeded(r, reason);
2809
2810                // We need to keep around the original state, in case we need to be created again.
2811                // But we only do this for pre-Honeycomb apps, which always save their state when
2812                // pausing, so we can not have them save their state when restarting from a paused
2813                // state. For HC and later, we want to (and can) let the state be saved as the
2814                // normal part of stopping the activity.
2815                if (r.isPreHoneycomb()) {
2816                    r.state = oldState;
2817                }
2818            }
2819        } else {
2820            // If there was an error, for any reason, tell the activity manager to stop us.
2821            try {
2822                ActivityManager.getService()
2823                    .finishActivity(r.token, Activity.RESULT_CANCELED, null,
2824                            Activity.DONT_FINISH_TASK_WITH_ACTIVITY);
2825            } catch (RemoteException ex) {
2826                throw ex.rethrowFromSystemServer();
2827            }
2828        }
2829    }
2830
2831    private void reportSizeConfigurations(ActivityClientRecord r) {
2832        Configuration[] configurations = r.activity.getResources().getSizeConfigurations();
2833        if (configurations == null) {
2834            return;
2835        }
2836        SparseIntArray horizontal = new SparseIntArray();
2837        SparseIntArray vertical = new SparseIntArray();
2838        SparseIntArray smallest = new SparseIntArray();
2839        for (int i = configurations.length - 1; i >= 0; i--) {
2840            Configuration config = configurations[i];
2841            if (config.screenHeightDp != Configuration.SCREEN_HEIGHT_DP_UNDEFINED) {
2842                vertical.put(config.screenHeightDp, 0);
2843            }
2844            if (config.screenWidthDp != Configuration.SCREEN_WIDTH_DP_UNDEFINED) {
2845                horizontal.put(config.screenWidthDp, 0);
2846            }
2847            if (config.smallestScreenWidthDp != Configuration.SMALLEST_SCREEN_WIDTH_DP_UNDEFINED) {
2848                smallest.put(config.smallestScreenWidthDp, 0);
2849            }
2850        }
2851        try {
2852            ActivityManager.getService().reportSizeConfigurations(r.token,
2853                    horizontal.copyKeys(), vertical.copyKeys(), smallest.copyKeys());
2854        } catch (RemoteException ex) {
2855            throw ex.rethrowFromSystemServer();
2856        }
2857
2858    }
2859
2860    private void deliverNewIntents(ActivityClientRecord r, List<ReferrerIntent> intents) {
2861        final int N = intents.size();
2862        for (int i=0; i<N; i++) {
2863            ReferrerIntent intent = intents.get(i);
2864            intent.setExtrasClassLoader(r.activity.getClassLoader());
2865            intent.prepareToEnterProcess();
2866            r.activity.mFragments.noteStateNotSaved();
2867            mInstrumentation.callActivityOnNewIntent(r.activity, intent);
2868        }
2869    }
2870
2871    void performNewIntents(IBinder token, List<ReferrerIntent> intents, boolean andPause) {
2872        final ActivityClientRecord r = mActivities.get(token);
2873        if (r == null) {
2874            return;
2875        }
2876
2877        final boolean resumed = !r.paused;
2878        if (resumed) {
2879            r.activity.mTemporaryPause = true;
2880            mInstrumentation.callActivityOnPause(r.activity);
2881        }
2882        deliverNewIntents(r, intents);
2883        if (resumed) {
2884            r.activity.performResume();
2885            r.activity.mTemporaryPause = false;
2886        }
2887
2888        if (r.paused && andPause) {
2889            // In this case the activity was in the paused state when we delivered the intent,
2890            // to guarantee onResume gets called after onNewIntent we temporarily resume the
2891            // activity and pause again as the caller wanted.
2892            performResumeActivity(token, false, "performNewIntents");
2893            performPauseActivityIfNeeded(r, "performNewIntents");
2894        }
2895    }
2896
2897    private void handleNewIntent(NewIntentData data) {
2898        performNewIntents(data.token, data.intents, data.andPause);
2899    }
2900
2901    public void handleRequestAssistContextExtras(RequestAssistContextExtras cmd) {
2902        // Filling for auto-fill has a few differences:
2903        // - it does not need an AssistContent
2904        // - it does not call onProvideAssistData()
2905        // - it needs an IAutoFillCallback
2906        // - it sets the flags so views can provide autofill-specific data (such as passwords)
2907        boolean forAutoFill = cmd.requestType == ActivityManager.ASSIST_CONTEXT_AUTO_FILL
2908                || cmd.requestType == ActivityManager.ASSIST_CONTEXT_AUTO_FILL_SAVE;
2909
2910        // TODO(b/33197203): decide if lastSessionId logic applies to auto-fill sessions
2911        if (mLastSessionId != cmd.sessionId) {
2912            // Clear the existing structures
2913            mLastSessionId = cmd.sessionId;
2914            for (int i = mLastAssistStructures.size() - 1; i >= 0; i--) {
2915                AssistStructure structure = mLastAssistStructures.get(i).get();
2916                if (structure != null) {
2917                    structure.clearSendChannel();
2918                }
2919                mLastAssistStructures.remove(i);
2920            }
2921        }
2922
2923        Bundle data = new Bundle();
2924        AssistStructure structure = null;
2925        AssistContent content = forAutoFill ? null : new AssistContent();
2926        ActivityClientRecord r = mActivities.get(cmd.activityToken);
2927        Uri referrer = null;
2928        if (r != null) {
2929            if (!forAutoFill) {
2930                r.activity.getApplication().dispatchOnProvideAssistData(r.activity, data);
2931                r.activity.onProvideAssistData(data);
2932                referrer = r.activity.onProvideReferrer();
2933            }
2934            if (cmd.requestType == ActivityManager.ASSIST_CONTEXT_FULL || forAutoFill) {
2935                structure = new AssistStructure(r.activity, cmd.flags);
2936                Intent activityIntent = r.activity.getIntent();
2937                if (forAutoFill) {
2938                    data.putInt(VoiceInteractionSession.KEY_FLAGS, cmd.flags);
2939                }
2940                boolean addAutoFillCallback = false;
2941                // TODO(b/33197203): re-evaluate conditions below for auto-fill. In particular,
2942                // FLAG_SECURE might be allowed on AUTO_FILL but not on AUTO_FILL_SAVE)
2943                boolean notSecure = r.window == null ||
2944                        (r.window.getAttributes().flags
2945                                & WindowManager.LayoutParams.FLAG_SECURE) == 0;
2946                if (activityIntent != null && notSecure) {
2947                    if (forAutoFill) {
2948                        addAutoFillCallback = true;
2949                    } else {
2950                        Intent intent = new Intent(activityIntent);
2951                        intent.setFlags(intent.getFlags() & ~(Intent.FLAG_GRANT_WRITE_URI_PERMISSION
2952                                | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION));
2953                        intent.removeUnsafeExtras();
2954                        content.setDefaultIntent(intent);
2955                    }
2956                } else {
2957                    if (!forAutoFill) {
2958                        content.setDefaultIntent(new Intent());
2959                    } else {
2960                        // activityIntent is unlikely to be null, but if it is, we should still
2961                        // set the auto-fill callback.
2962                        addAutoFillCallback = notSecure;
2963                    }
2964                }
2965                if (!forAutoFill) {
2966                    r.activity.onProvideAssistContent(content);
2967                } else if (addAutoFillCallback) {
2968                    IAutoFillAppCallback cb = r.activity.getAutoFillCallback().get();
2969                    if (cb != null) {
2970                        data.putBinder(AutoFillService.KEY_CALLBACK, cb.asBinder());
2971                    } else {
2972                        Slog.w(TAG, "handleRequestAssistContextExtras(): callback was GCed");
2973                    }
2974                }
2975            }
2976        }
2977        if (structure == null) {
2978            structure = new AssistStructure();
2979        }
2980        // TODO(b/33197203): decide if lastSessionId logic applies to auto-fill sessions
2981        mLastAssistStructures.add(new WeakReference<>(structure));
2982        IActivityManager mgr = ActivityManager.getService();
2983        try {
2984            mgr.reportAssistContextExtras(cmd.requestToken, data, structure, content, referrer);
2985        } catch (RemoteException e) {
2986            throw e.rethrowFromSystemServer();
2987        }
2988    }
2989
2990    public void handleTranslucentConversionComplete(IBinder token, boolean drawComplete) {
2991        ActivityClientRecord r = mActivities.get(token);
2992        if (r != null) {
2993            r.activity.onTranslucentConversionComplete(drawComplete);
2994        }
2995    }
2996
2997    public void onNewActivityOptions(IBinder token, ActivityOptions options) {
2998        ActivityClientRecord r = mActivities.get(token);
2999        if (r != null) {
3000            r.activity.onNewActivityOptions(options);
3001        }
3002    }
3003
3004    public void handleCancelVisibleBehind(IBinder token) {
3005        ActivityClientRecord r = mActivities.get(token);
3006        if (r != null) {
3007            mSomeActivitiesChanged = true;
3008            final Activity activity = r.activity;
3009            if (activity.mVisibleBehind) {
3010                activity.mCalled = false;
3011                activity.onVisibleBehindCanceled();
3012                // Tick, tick, tick. The activity has 500 msec to return or it will be destroyed.
3013                if (!activity.mCalled) {
3014                    throw new SuperNotCalledException("Activity " + activity.getLocalClassName() +
3015                            " did not call through to super.onVisibleBehindCanceled()");
3016                }
3017                activity.mVisibleBehind = false;
3018            }
3019        }
3020        try {
3021            ActivityManager.getService().backgroundResourcesReleased(token);
3022        } catch (RemoteException e) {
3023            throw e.rethrowFromSystemServer();
3024        }
3025    }
3026
3027    public void handleOnBackgroundVisibleBehindChanged(IBinder token, boolean visible) {
3028        ActivityClientRecord r = mActivities.get(token);
3029        if (r != null) {
3030            r.activity.onBackgroundVisibleBehindChanged(visible);
3031        }
3032    }
3033
3034    public void handleInstallProvider(ProviderInfo info) {
3035        final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
3036        try {
3037            installContentProviders(mInitialApplication, Lists.newArrayList(info));
3038        } finally {
3039            StrictMode.setThreadPolicy(oldPolicy);
3040        }
3041    }
3042
3043    private void handleEnterAnimationComplete(IBinder token) {
3044        ActivityClientRecord r = mActivities.get(token);
3045        if (r != null) {
3046            r.activity.dispatchEnterAnimationComplete();
3047        }
3048    }
3049
3050    private void handleStartBinderTracking() {
3051        Binder.enableTracing();
3052    }
3053
3054    private void handleStopBinderTrackingAndDump(ParcelFileDescriptor fd) {
3055        try {
3056            Binder.disableTracing();
3057            Binder.getTransactionTracker().writeTracesToFile(fd);
3058        } finally {
3059            IoUtils.closeQuietly(fd);
3060            Binder.getTransactionTracker().clearTraces();
3061        }
3062    }
3063
3064    private void handleMultiWindowModeChanged(IBinder token, boolean isInMultiWindowMode) {
3065        final ActivityClientRecord r = mActivities.get(token);
3066        if (r != null) {
3067            r.activity.dispatchMultiWindowModeChanged(isInMultiWindowMode);
3068        }
3069    }
3070
3071    private void handlePictureInPictureModeChanged(IBinder token, boolean isInPipMode) {
3072        final ActivityClientRecord r = mActivities.get(token);
3073        if (r != null) {
3074            r.activity.dispatchPictureInPictureModeChanged(isInPipMode);
3075        }
3076    }
3077
3078    private void handleLocalVoiceInteractionStarted(IBinder token, IVoiceInteractor interactor) {
3079        final ActivityClientRecord r = mActivities.get(token);
3080        if (r != null) {
3081            r.voiceInteractor = interactor;
3082            r.activity.setVoiceInteractor(interactor);
3083            if (interactor == null) {
3084                r.activity.onLocalVoiceInteractionStopped();
3085            } else {
3086                r.activity.onLocalVoiceInteractionStarted();
3087            }
3088        }
3089    }
3090
3091    static final void handleAttachAgent(String agent) {
3092        try {
3093            VMDebug.attachAgent(agent);
3094        } catch (IOException e) {
3095            Slog.e(TAG, "Attaching agent failed: " + agent);
3096        }
3097    }
3098
3099    private static final ThreadLocal<Intent> sCurrentBroadcastIntent = new ThreadLocal<Intent>();
3100
3101    /**
3102     * Return the Intent that's currently being handled by a
3103     * BroadcastReceiver on this thread, or null if none.
3104     * @hide
3105     */
3106    public static Intent getIntentBeingBroadcast() {
3107        return sCurrentBroadcastIntent.get();
3108    }
3109
3110    private void handleReceiver(ReceiverData data) {
3111        // If we are getting ready to gc after going to the background, well
3112        // we are back active so skip it.
3113        unscheduleGcIdler();
3114
3115        String component = data.intent.getComponent().getClassName();
3116
3117        LoadedApk packageInfo = getPackageInfoNoCheck(
3118                data.info.applicationInfo, data.compatInfo);
3119
3120        IActivityManager mgr = ActivityManager.getService();
3121
3122        BroadcastReceiver receiver;
3123        try {
3124            java.lang.ClassLoader cl = packageInfo.getClassLoader();
3125            data.intent.setExtrasClassLoader(cl);
3126            data.intent.prepareToEnterProcess();
3127            data.setExtrasClassLoader(cl);
3128            receiver = (BroadcastReceiver)cl.loadClass(component).newInstance();
3129        } catch (Exception e) {
3130            if (DEBUG_BROADCAST) Slog.i(TAG,
3131                    "Finishing failed broadcast to " + data.intent.getComponent());
3132            data.sendFinished(mgr);
3133            throw new RuntimeException(
3134                "Unable to instantiate receiver " + component
3135                + ": " + e.toString(), e);
3136        }
3137
3138        try {
3139            Application app = packageInfo.makeApplication(false, mInstrumentation);
3140
3141            if (localLOGV) Slog.v(
3142                TAG, "Performing receive of " + data.intent
3143                + ": app=" + app
3144                + ", appName=" + app.getPackageName()
3145                + ", pkg=" + packageInfo.getPackageName()
3146                + ", comp=" + data.intent.getComponent().toShortString()
3147                + ", dir=" + packageInfo.getAppDir());
3148
3149            ContextImpl context = (ContextImpl)app.getBaseContext();
3150            sCurrentBroadcastIntent.set(data.intent);
3151            receiver.setPendingResult(data);
3152            receiver.onReceive(context.getReceiverRestrictedContext(),
3153                    data.intent);
3154        } catch (Exception e) {
3155            if (DEBUG_BROADCAST) Slog.i(TAG,
3156                    "Finishing failed broadcast to " + data.intent.getComponent());
3157            data.sendFinished(mgr);
3158            if (!mInstrumentation.onException(receiver, e)) {
3159                throw new RuntimeException(
3160                    "Unable to start receiver " + component
3161                    + ": " + e.toString(), e);
3162            }
3163        } finally {
3164            sCurrentBroadcastIntent.set(null);
3165        }
3166
3167        if (receiver.getPendingResult() != null) {
3168            data.finish();
3169        }
3170    }
3171
3172    // Instantiate a BackupAgent and tell it that it's alive
3173    private void handleCreateBackupAgent(CreateBackupAgentData data) {
3174        if (DEBUG_BACKUP) Slog.v(TAG, "handleCreateBackupAgent: " + data);
3175
3176        // Sanity check the requested target package's uid against ours
3177        try {
3178            PackageInfo requestedPackage = getPackageManager().getPackageInfo(
3179                    data.appInfo.packageName, 0, UserHandle.myUserId());
3180            if (requestedPackage.applicationInfo.uid != Process.myUid()) {
3181                Slog.w(TAG, "Asked to instantiate non-matching package "
3182                        + data.appInfo.packageName);
3183                return;
3184            }
3185        } catch (RemoteException e) {
3186            throw e.rethrowFromSystemServer();
3187        }
3188
3189        // no longer idle; we have backup work to do
3190        unscheduleGcIdler();
3191
3192        // instantiate the BackupAgent class named in the manifest
3193        LoadedApk packageInfo = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
3194        String packageName = packageInfo.mPackageName;
3195        if (packageName == null) {
3196            Slog.d(TAG, "Asked to create backup agent for nonexistent package");
3197            return;
3198        }
3199
3200        String classname = data.appInfo.backupAgentName;
3201        // full backup operation but no app-supplied agent?  use the default implementation
3202        if (classname == null && (data.backupMode == ApplicationThreadConstants.BACKUP_MODE_FULL
3203                || data.backupMode == ApplicationThreadConstants.BACKUP_MODE_RESTORE_FULL)) {
3204            classname = "android.app.backup.FullBackupAgent";
3205        }
3206
3207        try {
3208            IBinder binder = null;
3209            BackupAgent agent = mBackupAgents.get(packageName);
3210            if (agent != null) {
3211                // reusing the existing instance
3212                if (DEBUG_BACKUP) {
3213                    Slog.v(TAG, "Reusing existing agent instance");
3214                }
3215                binder = agent.onBind();
3216            } else {
3217                try {
3218                    if (DEBUG_BACKUP) Slog.v(TAG, "Initializing agent class " + classname);
3219
3220                    java.lang.ClassLoader cl = packageInfo.getClassLoader();
3221                    agent = (BackupAgent) cl.loadClass(classname).newInstance();
3222
3223                    // set up the agent's context
3224                    ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
3225                    context.setOuterContext(agent);
3226                    agent.attach(context);
3227
3228                    agent.onCreate();
3229                    binder = agent.onBind();
3230                    mBackupAgents.put(packageName, agent);
3231                } catch (Exception e) {
3232                    // If this is during restore, fail silently; otherwise go
3233                    // ahead and let the user see the crash.
3234                    Slog.e(TAG, "Agent threw during creation: " + e);
3235                    if (data.backupMode != ApplicationThreadConstants.BACKUP_MODE_RESTORE
3236                            && data.backupMode !=
3237                                    ApplicationThreadConstants.BACKUP_MODE_RESTORE_FULL) {
3238                        throw e;
3239                    }
3240                    // falling through with 'binder' still null
3241                }
3242            }
3243
3244            // tell the OS that we're live now
3245            try {
3246                ActivityManager.getService().backupAgentCreated(packageName, binder);
3247            } catch (RemoteException e) {
3248                throw e.rethrowFromSystemServer();
3249            }
3250        } catch (Exception e) {
3251            throw new RuntimeException("Unable to create BackupAgent "
3252                    + classname + ": " + e.toString(), e);
3253        }
3254    }
3255
3256    // Tear down a BackupAgent
3257    private void handleDestroyBackupAgent(CreateBackupAgentData data) {
3258        if (DEBUG_BACKUP) Slog.v(TAG, "handleDestroyBackupAgent: " + data);
3259
3260        LoadedApk packageInfo = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
3261        String packageName = packageInfo.mPackageName;
3262        BackupAgent agent = mBackupAgents.get(packageName);
3263        if (agent != null) {
3264            try {
3265                agent.onDestroy();
3266            } catch (Exception e) {
3267                Slog.w(TAG, "Exception thrown in onDestroy by backup agent of " + data.appInfo);
3268                e.printStackTrace();
3269            }
3270            mBackupAgents.remove(packageName);
3271        } else {
3272            Slog.w(TAG, "Attempt to destroy unknown backup agent " + data);
3273        }
3274    }
3275
3276    private void handleCreateService(CreateServiceData data) {
3277        // If we are getting ready to gc after going to the background, well
3278        // we are back active so skip it.
3279        unscheduleGcIdler();
3280
3281        LoadedApk packageInfo = getPackageInfoNoCheck(
3282                data.info.applicationInfo, data.compatInfo);
3283        Service service = null;
3284        try {
3285            java.lang.ClassLoader cl = packageInfo.getClassLoader();
3286            service = (Service) cl.loadClass(data.info.name).newInstance();
3287        } catch (Exception e) {
3288            if (!mInstrumentation.onException(service, e)) {
3289                throw new RuntimeException(
3290                    "Unable to instantiate service " + data.info.name
3291                    + ": " + e.toString(), e);
3292            }
3293        }
3294
3295        try {
3296            if (localLOGV) Slog.v(TAG, "Creating service " + data.info.name);
3297
3298            ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
3299            context.setOuterContext(service);
3300
3301            Application app = packageInfo.makeApplication(false, mInstrumentation);
3302            service.attach(context, this, data.info.name, data.token, app,
3303                    ActivityManager.getService());
3304            service.onCreate();
3305            mServices.put(data.token, service);
3306            try {
3307                ActivityManager.getService().serviceDoneExecuting(
3308                        data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
3309            } catch (RemoteException e) {
3310                throw e.rethrowFromSystemServer();
3311            }
3312        } catch (Exception e) {
3313            if (!mInstrumentation.onException(service, e)) {
3314                throw new RuntimeException(
3315                    "Unable to create service " + data.info.name
3316                    + ": " + e.toString(), e);
3317            }
3318        }
3319    }
3320
3321    private void handleBindService(BindServiceData data) {
3322        Service s = mServices.get(data.token);
3323        if (DEBUG_SERVICE)
3324            Slog.v(TAG, "handleBindService s=" + s + " rebind=" + data.rebind);
3325        if (s != null) {
3326            try {
3327                data.intent.setExtrasClassLoader(s.getClassLoader());
3328                data.intent.prepareToEnterProcess();
3329                try {
3330                    if (!data.rebind) {
3331                        IBinder binder = s.onBind(data.intent);
3332                        ActivityManager.getService().publishService(
3333                                data.token, data.intent, binder);
3334                    } else {
3335                        s.onRebind(data.intent);
3336                        ActivityManager.getService().serviceDoneExecuting(
3337                                data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
3338                    }
3339                    ensureJitEnabled();
3340                } catch (RemoteException ex) {
3341                    throw ex.rethrowFromSystemServer();
3342                }
3343            } catch (Exception e) {
3344                if (!mInstrumentation.onException(s, e)) {
3345                    throw new RuntimeException(
3346                            "Unable to bind to service " + s
3347                            + " with " + data.intent + ": " + e.toString(), e);
3348                }
3349            }
3350        }
3351    }
3352
3353    private void handleUnbindService(BindServiceData data) {
3354        Service s = mServices.get(data.token);
3355        if (s != null) {
3356            try {
3357                data.intent.setExtrasClassLoader(s.getClassLoader());
3358                data.intent.prepareToEnterProcess();
3359                boolean doRebind = s.onUnbind(data.intent);
3360                try {
3361                    if (doRebind) {
3362                        ActivityManager.getService().unbindFinished(
3363                                data.token, data.intent, doRebind);
3364                    } else {
3365                        ActivityManager.getService().serviceDoneExecuting(
3366                                data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
3367                    }
3368                } catch (RemoteException ex) {
3369                    throw ex.rethrowFromSystemServer();
3370                }
3371            } catch (Exception e) {
3372                if (!mInstrumentation.onException(s, e)) {
3373                    throw new RuntimeException(
3374                            "Unable to unbind to service " + s
3375                            + " with " + data.intent + ": " + e.toString(), e);
3376                }
3377            }
3378        }
3379    }
3380
3381    private void handleDumpService(DumpComponentInfo info) {
3382        final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
3383        try {
3384            Service s = mServices.get(info.token);
3385            if (s != null) {
3386                PrintWriter pw = new FastPrintWriter(new FileOutputStream(
3387                        info.fd.getFileDescriptor()));
3388                s.dump(info.fd.getFileDescriptor(), pw, info.args);
3389                pw.flush();
3390            }
3391        } finally {
3392            IoUtils.closeQuietly(info.fd);
3393            StrictMode.setThreadPolicy(oldPolicy);
3394        }
3395    }
3396
3397    private void handleDumpActivity(DumpComponentInfo info) {
3398        final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
3399        try {
3400            ActivityClientRecord r = mActivities.get(info.token);
3401            if (r != null && r.activity != null) {
3402                PrintWriter pw = new FastPrintWriter(new FileOutputStream(
3403                        info.fd.getFileDescriptor()));
3404                r.activity.dump(info.prefix, info.fd.getFileDescriptor(), pw, info.args);
3405                pw.flush();
3406            }
3407        } finally {
3408            IoUtils.closeQuietly(info.fd);
3409            StrictMode.setThreadPolicy(oldPolicy);
3410        }
3411    }
3412
3413    private void handleDumpProvider(DumpComponentInfo info) {
3414        final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
3415        try {
3416            ProviderClientRecord r = mLocalProviders.get(info.token);
3417            if (r != null && r.mLocalProvider != null) {
3418                PrintWriter pw = new FastPrintWriter(new FileOutputStream(
3419                        info.fd.getFileDescriptor()));
3420                r.mLocalProvider.dump(info.fd.getFileDescriptor(), pw, info.args);
3421                pw.flush();
3422            }
3423        } finally {
3424            IoUtils.closeQuietly(info.fd);
3425            StrictMode.setThreadPolicy(oldPolicy);
3426        }
3427    }
3428
3429    private void handleServiceArgs(ServiceArgsData data) {
3430        Service s = mServices.get(data.token);
3431        if (s != null) {
3432            try {
3433                if (data.args != null) {
3434                    data.args.setExtrasClassLoader(s.getClassLoader());
3435                    data.args.prepareToEnterProcess();
3436                }
3437                int res;
3438                if (!data.taskRemoved) {
3439                    res = s.onStartCommand(data.args, data.flags, data.startId);
3440                } else {
3441                    s.onTaskRemoved(data.args);
3442                    res = Service.START_TASK_REMOVED_COMPLETE;
3443                }
3444
3445                QueuedWork.waitToFinish();
3446
3447                try {
3448                    ActivityManager.getService().serviceDoneExecuting(
3449                            data.token, SERVICE_DONE_EXECUTING_START, data.startId, res);
3450                } catch (RemoteException e) {
3451                    throw e.rethrowFromSystemServer();
3452                }
3453                ensureJitEnabled();
3454            } catch (Exception e) {
3455                if (!mInstrumentation.onException(s, e)) {
3456                    throw new RuntimeException(
3457                            "Unable to start service " + s
3458                            + " with " + data.args + ": " + e.toString(), e);
3459                }
3460            }
3461        }
3462    }
3463
3464    private void handleStopService(IBinder token) {
3465        Service s = mServices.remove(token);
3466        if (s != null) {
3467            try {
3468                if (localLOGV) Slog.v(TAG, "Destroying service " + s);
3469                s.onDestroy();
3470                Context context = s.getBaseContext();
3471                if (context instanceof ContextImpl) {
3472                    final String who = s.getClassName();
3473                    ((ContextImpl) context).scheduleFinalCleanup(who, "Service");
3474                }
3475
3476                QueuedWork.waitToFinish();
3477
3478                try {
3479                    ActivityManager.getService().serviceDoneExecuting(
3480                            token, SERVICE_DONE_EXECUTING_STOP, 0, 0);
3481                } catch (RemoteException e) {
3482                    throw e.rethrowFromSystemServer();
3483                }
3484            } catch (Exception e) {
3485                if (!mInstrumentation.onException(s, e)) {
3486                    throw new RuntimeException(
3487                            "Unable to stop service " + s
3488                            + ": " + e.toString(), e);
3489                }
3490                Slog.i(TAG, "handleStopService: exception for " + token, e);
3491            }
3492        } else {
3493            Slog.i(TAG, "handleStopService: token=" + token + " not found.");
3494        }
3495        //Slog.i(TAG, "Running services: " + mServices);
3496    }
3497
3498    public final ActivityClientRecord performResumeActivity(IBinder token,
3499            boolean clearHide, String reason) {
3500        ActivityClientRecord r = mActivities.get(token);
3501        if (localLOGV) Slog.v(TAG, "Performing resume of " + r
3502                + " finished=" + r.activity.mFinished);
3503        if (r != null && !r.activity.mFinished) {
3504            if (clearHide) {
3505                r.hideForNow = false;
3506                r.activity.mStartedActivity = false;
3507            }
3508            try {
3509                r.activity.onStateNotSaved();
3510                r.activity.mFragments.noteStateNotSaved();
3511                if (r.pendingIntents != null) {
3512                    deliverNewIntents(r, r.pendingIntents);
3513                    r.pendingIntents = null;
3514                }
3515                if (r.pendingResults != null) {
3516                    deliverResults(r, r.pendingResults);
3517                    r.pendingResults = null;
3518                }
3519                r.activity.performResume();
3520
3521                synchronized (mResourcesManager) {
3522                    // If there is a pending local relaunch that was requested when the activity was
3523                    // paused, it will put the activity into paused state when it finally happens.
3524                    // Since the activity resumed before being relaunched, we don't want that to
3525                    // happen, so we need to clear the request to relaunch paused.
3526                    for (int i = mRelaunchingActivities.size() - 1; i >= 0; i--) {
3527                        final ActivityClientRecord relaunching = mRelaunchingActivities.get(i);
3528                        if (relaunching.token == r.token
3529                                && relaunching.onlyLocalRequest && relaunching.startsNotResumed) {
3530                            relaunching.startsNotResumed = false;
3531                        }
3532                    }
3533                }
3534
3535                EventLog.writeEvent(LOG_AM_ON_RESUME_CALLED, UserHandle.myUserId(),
3536                        r.activity.getComponentName().getClassName(), reason);
3537
3538                r.paused = false;
3539                r.stopped = false;
3540                r.state = null;
3541                r.persistentState = null;
3542            } catch (Exception e) {
3543                if (!mInstrumentation.onException(r.activity, e)) {
3544                    throw new RuntimeException(
3545                        "Unable to resume activity "
3546                        + r.intent.getComponent().toShortString()
3547                        + ": " + e.toString(), e);
3548                }
3549            }
3550        }
3551        return r;
3552    }
3553
3554    static final void cleanUpPendingRemoveWindows(ActivityClientRecord r, boolean force) {
3555        if (r.mPreserveWindow && !force) {
3556            return;
3557        }
3558        if (r.mPendingRemoveWindow != null) {
3559            r.mPendingRemoveWindowManager.removeViewImmediate(
3560                    r.mPendingRemoveWindow.getDecorView());
3561            IBinder wtoken = r.mPendingRemoveWindow.getDecorView().getWindowToken();
3562            if (wtoken != null) {
3563                WindowManagerGlobal.getInstance().closeAll(wtoken,
3564                        r.activity.getClass().getName(), "Activity");
3565            }
3566        }
3567        r.mPendingRemoveWindow = null;
3568        r.mPendingRemoveWindowManager = null;
3569    }
3570
3571    final void handleResumeActivity(IBinder token,
3572            boolean clearHide, boolean isForward, boolean reallyResume, int seq, String reason) {
3573        ActivityClientRecord r = mActivities.get(token);
3574        if (!checkAndUpdateLifecycleSeq(seq, r, "resumeActivity")) {
3575            return;
3576        }
3577
3578        // If we are getting ready to gc after going to the background, well
3579        // we are back active so skip it.
3580        unscheduleGcIdler();
3581        mSomeActivitiesChanged = true;
3582
3583        // TODO Push resumeArgs into the activity for consideration
3584        r = performResumeActivity(token, clearHide, reason);
3585
3586        if (r != null) {
3587            final Activity a = r.activity;
3588
3589            if (localLOGV) Slog.v(
3590                TAG, "Resume " + r + " started activity: " +
3591                a.mStartedActivity + ", hideForNow: " + r.hideForNow
3592                + ", finished: " + a.mFinished);
3593
3594            final int forwardBit = isForward ?
3595                    WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION : 0;
3596
3597            // If the window hasn't yet been added to the window manager,
3598            // and this guy didn't finish itself or start another activity,
3599            // then go ahead and add the window.
3600            boolean willBeVisible = !a.mStartedActivity;
3601            if (!willBeVisible) {
3602                try {
3603                    willBeVisible = ActivityManager.getService().willActivityBeVisible(
3604                            a.getActivityToken());
3605                } catch (RemoteException e) {
3606                    throw e.rethrowFromSystemServer();
3607                }
3608            }
3609            if (r.window == null && !a.mFinished && willBeVisible) {
3610                r.window = r.activity.getWindow();
3611                View decor = r.window.getDecorView();
3612                decor.setVisibility(View.INVISIBLE);
3613                ViewManager wm = a.getWindowManager();
3614                WindowManager.LayoutParams l = r.window.getAttributes();
3615                a.mDecor = decor;
3616                l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
3617                l.softInputMode |= forwardBit;
3618                if (r.mPreserveWindow) {
3619                    a.mWindowAdded = true;
3620                    r.mPreserveWindow = false;
3621                    // Normally the ViewRoot sets up callbacks with the Activity
3622                    // in addView->ViewRootImpl#setView. If we are instead reusing
3623                    // the decor view we have to notify the view root that the
3624                    // callbacks may have changed.
3625                    ViewRootImpl impl = decor.getViewRootImpl();
3626                    if (impl != null) {
3627                        impl.notifyChildRebuilt();
3628                    }
3629                }
3630                if (a.mVisibleFromClient && !a.mWindowAdded) {
3631                    a.mWindowAdded = true;
3632                    wm.addView(decor, l);
3633                }
3634
3635            // If the window has already been added, but during resume
3636            // we started another activity, then don't yet make the
3637            // window visible.
3638            } else if (!willBeVisible) {
3639                if (localLOGV) Slog.v(
3640                    TAG, "Launch " + r + " mStartedActivity set");
3641                r.hideForNow = true;
3642            }
3643
3644            // Get rid of anything left hanging around.
3645            cleanUpPendingRemoveWindows(r, false /* force */);
3646
3647            // The window is now visible if it has been added, we are not
3648            // simply finishing, and we are not starting another activity.
3649            if (!r.activity.mFinished && willBeVisible
3650                    && r.activity.mDecor != null && !r.hideForNow) {
3651                if (r.newConfig != null) {
3652                    performConfigurationChangedForActivity(r, r.newConfig, REPORT_TO_ACTIVITY);
3653                    if (DEBUG_CONFIGURATION) Slog.v(TAG, "Resuming activity "
3654                            + r.activityInfo.name + " with newConfig " + r.activity.mCurrentConfig);
3655                    r.newConfig = null;
3656                }
3657                if (localLOGV) Slog.v(TAG, "Resuming " + r + " with isForward="
3658                        + isForward);
3659                WindowManager.LayoutParams l = r.window.getAttributes();
3660                if ((l.softInputMode
3661                        & WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION)
3662                        != forwardBit) {
3663                    l.softInputMode = (l.softInputMode
3664                            & (~WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION))
3665                            | forwardBit;
3666                    if (r.activity.mVisibleFromClient) {
3667                        ViewManager wm = a.getWindowManager();
3668                        View decor = r.window.getDecorView();
3669                        wm.updateViewLayout(decor, l);
3670                    }
3671                }
3672                r.activity.mVisibleFromServer = true;
3673                mNumVisibleActivities++;
3674                if (r.activity.mVisibleFromClient) {
3675                    r.activity.makeVisible();
3676                }
3677            }
3678
3679            if (!r.onlyLocalRequest) {
3680                r.nextIdle = mNewActivities;
3681                mNewActivities = r;
3682                if (localLOGV) Slog.v(
3683                    TAG, "Scheduling idle handler for " + r);
3684                Looper.myQueue().addIdleHandler(new Idler());
3685            }
3686            r.onlyLocalRequest = false;
3687
3688            // Tell the activity manager we have resumed.
3689            if (reallyResume) {
3690                try {
3691                    ActivityManager.getService().activityResumed(token);
3692                } catch (RemoteException ex) {
3693                    throw ex.rethrowFromSystemServer();
3694                }
3695            }
3696
3697        } else {
3698            // If an exception was thrown when trying to resume, then
3699            // just end this activity.
3700            try {
3701                ActivityManager.getService()
3702                    .finishActivity(token, Activity.RESULT_CANCELED, null,
3703                            Activity.DONT_FINISH_TASK_WITH_ACTIVITY);
3704            } catch (RemoteException ex) {
3705                throw ex.rethrowFromSystemServer();
3706            }
3707        }
3708    }
3709
3710    private int mThumbnailWidth = -1;
3711    private int mThumbnailHeight = -1;
3712    private Bitmap mAvailThumbnailBitmap = null;
3713    private Canvas mThumbnailCanvas = null;
3714
3715    private Bitmap createThumbnailBitmap(ActivityClientRecord r) {
3716        Bitmap thumbnail = mAvailThumbnailBitmap;
3717        try {
3718            if (thumbnail == null) {
3719                int w = mThumbnailWidth;
3720                int h;
3721                if (w < 0) {
3722                    Resources res = r.activity.getResources();
3723                    int wId = com.android.internal.R.dimen.thumbnail_width;
3724                    int hId = com.android.internal.R.dimen.thumbnail_height;
3725                    mThumbnailWidth = w = res.getDimensionPixelSize(wId);
3726                    mThumbnailHeight = h = res.getDimensionPixelSize(hId);
3727                } else {
3728                    h = mThumbnailHeight;
3729                }
3730
3731                // On platforms where we don't want thumbnails, set dims to (0,0)
3732                if ((w > 0) && (h > 0)) {
3733                    thumbnail = Bitmap.createBitmap(r.activity.getResources().getDisplayMetrics(),
3734                            w, h, THUMBNAIL_FORMAT);
3735                    thumbnail.eraseColor(0);
3736                }
3737            }
3738
3739            if (thumbnail != null) {
3740                Canvas cv = mThumbnailCanvas;
3741                if (cv == null) {
3742                    mThumbnailCanvas = cv = new Canvas();
3743                }
3744
3745                cv.setBitmap(thumbnail);
3746                if (!r.activity.onCreateThumbnail(thumbnail, cv)) {
3747                    mAvailThumbnailBitmap = thumbnail;
3748                    thumbnail = null;
3749                }
3750                cv.setBitmap(null);
3751            }
3752
3753        } catch (Exception e) {
3754            if (!mInstrumentation.onException(r.activity, e)) {
3755                throw new RuntimeException(
3756                        "Unable to create thumbnail of "
3757                        + r.intent.getComponent().toShortString()
3758                        + ": " + e.toString(), e);
3759            }
3760            thumbnail = null;
3761        }
3762
3763        return thumbnail;
3764    }
3765
3766    private void handlePauseActivity(IBinder token, boolean finished,
3767            boolean userLeaving, int configChanges, boolean dontReport, int seq) {
3768        ActivityClientRecord r = mActivities.get(token);
3769        if (DEBUG_ORDER) Slog.d(TAG, "handlePauseActivity " + r + ", seq: " + seq);
3770        if (!checkAndUpdateLifecycleSeq(seq, r, "pauseActivity")) {
3771            return;
3772        }
3773        if (r != null) {
3774            //Slog.v(TAG, "userLeaving=" + userLeaving + " handling pause of " + r);
3775            if (userLeaving) {
3776                performUserLeavingActivity(r);
3777            }
3778
3779            r.activity.mConfigChangeFlags |= configChanges;
3780            performPauseActivity(token, finished, r.isPreHoneycomb(), "handlePauseActivity");
3781
3782            // Make sure any pending writes are now committed.
3783            if (r.isPreHoneycomb()) {
3784                QueuedWork.waitToFinish();
3785            }
3786
3787            // Tell the activity manager we have paused.
3788            if (!dontReport) {
3789                try {
3790                    ActivityManager.getService().activityPaused(token);
3791                } catch (RemoteException ex) {
3792                    throw ex.rethrowFromSystemServer();
3793                }
3794            }
3795            mSomeActivitiesChanged = true;
3796        }
3797    }
3798
3799    final void performUserLeavingActivity(ActivityClientRecord r) {
3800        mInstrumentation.callActivityOnUserLeaving(r.activity);
3801    }
3802
3803    final Bundle performPauseActivity(IBinder token, boolean finished,
3804            boolean saveState, String reason) {
3805        ActivityClientRecord r = mActivities.get(token);
3806        return r != null ? performPauseActivity(r, finished, saveState, reason) : null;
3807    }
3808
3809    final Bundle performPauseActivity(ActivityClientRecord r, boolean finished,
3810            boolean saveState, String reason) {
3811        if (r.paused) {
3812            if (r.activity.mFinished) {
3813                // If we are finishing, we won't call onResume() in certain cases.
3814                // So here we likewise don't want to call onPause() if the activity
3815                // isn't resumed.
3816                return null;
3817            }
3818            RuntimeException e = new RuntimeException(
3819                    "Performing pause of activity that is not resumed: "
3820                    + r.intent.getComponent().toShortString());
3821            Slog.e(TAG, e.getMessage(), e);
3822        }
3823        if (finished) {
3824            r.activity.mFinished = true;
3825        }
3826
3827        // Next have the activity save its current state and managed dialogs...
3828        if (!r.activity.mFinished && saveState) {
3829            callCallActivityOnSaveInstanceState(r);
3830        }
3831
3832        performPauseActivityIfNeeded(r, reason);
3833
3834        // Notify any outstanding on paused listeners
3835        ArrayList<OnActivityPausedListener> listeners;
3836        synchronized (mOnPauseListeners) {
3837            listeners = mOnPauseListeners.remove(r.activity);
3838        }
3839        int size = (listeners != null ? listeners.size() : 0);
3840        for (int i = 0; i < size; i++) {
3841            listeners.get(i).onPaused(r.activity);
3842        }
3843
3844        return !r.activity.mFinished && saveState ? r.state : null;
3845    }
3846
3847    private void performPauseActivityIfNeeded(ActivityClientRecord r, String reason) {
3848        if (r.paused) {
3849            // You are already paused silly...
3850            return;
3851        }
3852
3853        try {
3854            r.activity.mCalled = false;
3855            mInstrumentation.callActivityOnPause(r.activity);
3856            EventLog.writeEvent(LOG_AM_ON_PAUSE_CALLED, UserHandle.myUserId(),
3857                    r.activity.getComponentName().getClassName(), reason);
3858            if (!r.activity.mCalled) {
3859                throw new SuperNotCalledException("Activity " + safeToComponentShortString(r.intent)
3860                        + " did not call through to super.onPause()");
3861            }
3862        } catch (SuperNotCalledException e) {
3863            throw e;
3864        } catch (Exception e) {
3865            if (!mInstrumentation.onException(r.activity, e)) {
3866                throw new RuntimeException("Unable to pause activity "
3867                        + safeToComponentShortString(r.intent) + ": " + e.toString(), e);
3868            }
3869        }
3870        r.paused = true;
3871    }
3872
3873    final void performStopActivity(IBinder token, boolean saveState, String reason) {
3874        ActivityClientRecord r = mActivities.get(token);
3875        performStopActivityInner(r, null, false, saveState, reason);
3876    }
3877
3878    private static class StopInfo implements Runnable {
3879        ActivityClientRecord activity;
3880        Bundle state;
3881        PersistableBundle persistentState;
3882        CharSequence description;
3883
3884        @Override public void run() {
3885            // Tell activity manager we have been stopped.
3886            try {
3887                if (DEBUG_MEMORY_TRIM) Slog.v(TAG, "Reporting activity stopped: " + activity);
3888                ActivityManager.getService().activityStopped(
3889                    activity.token, state, persistentState, description);
3890            } catch (RemoteException ex) {
3891                if (ex instanceof TransactionTooLargeException
3892                        && activity.packageInfo.getTargetSdkVersion() < Build.VERSION_CODES.N) {
3893                    Log.e(TAG, "App sent too much data in instance state, so it was ignored", ex);
3894                    return;
3895                }
3896                throw ex.rethrowFromSystemServer();
3897            }
3898        }
3899    }
3900
3901    private static final class ProviderRefCount {
3902        public final ContentProviderHolder holder;
3903        public final ProviderClientRecord client;
3904        public int stableCount;
3905        public int unstableCount;
3906
3907        // When this is set, the stable and unstable ref counts are 0 and
3908        // we have a pending operation scheduled to remove the ref count
3909        // from the activity manager.  On the activity manager we are still
3910        // holding an unstable ref, though it is not reflected in the counts
3911        // here.
3912        public boolean removePending;
3913
3914        ProviderRefCount(ContentProviderHolder inHolder,
3915                ProviderClientRecord inClient, int sCount, int uCount) {
3916            holder = inHolder;
3917            client = inClient;
3918            stableCount = sCount;
3919            unstableCount = uCount;
3920        }
3921    }
3922
3923    /**
3924     * Core implementation of stopping an activity.  Note this is a little
3925     * tricky because the server's meaning of stop is slightly different
3926     * than our client -- for the server, stop means to save state and give
3927     * it the result when it is done, but the window may still be visible.
3928     * For the client, we want to call onStop()/onStart() to indicate when
3929     * the activity's UI visibility changes.
3930     */
3931    private void performStopActivityInner(ActivityClientRecord r,
3932            StopInfo info, boolean keepShown, boolean saveState, String reason) {
3933        if (localLOGV) Slog.v(TAG, "Performing stop of " + r);
3934        if (r != null) {
3935            if (!keepShown && r.stopped) {
3936                if (r.activity.mFinished) {
3937                    // If we are finishing, we won't call onResume() in certain
3938                    // cases.  So here we likewise don't want to call onStop()
3939                    // if the activity isn't resumed.
3940                    return;
3941                }
3942                RuntimeException e = new RuntimeException(
3943                        "Performing stop of activity that is already stopped: "
3944                        + r.intent.getComponent().toShortString());
3945                Slog.e(TAG, e.getMessage(), e);
3946                Slog.e(TAG, r.getStateString());
3947            }
3948
3949            // One must first be paused before stopped...
3950            performPauseActivityIfNeeded(r, reason);
3951
3952            if (info != null) {
3953                try {
3954                    // First create a thumbnail for the activity...
3955                    // For now, don't create the thumbnail here; we are
3956                    // doing that by doing a screen snapshot.
3957                    info.description = r.activity.onCreateDescription();
3958                } catch (Exception e) {
3959                    if (!mInstrumentation.onException(r.activity, e)) {
3960                        throw new RuntimeException(
3961                                "Unable to save state of activity "
3962                                + r.intent.getComponent().toShortString()
3963                                + ": " + e.toString(), e);
3964                    }
3965                }
3966            }
3967
3968            // Next have the activity save its current state and managed dialogs...
3969            if (!r.activity.mFinished && saveState) {
3970                if (r.state == null) {
3971                    callCallActivityOnSaveInstanceState(r);
3972                }
3973            }
3974
3975            if (!keepShown) {
3976                try {
3977                    // Now we are idle.
3978                    r.activity.performStop(false /*preserveWindow*/);
3979                } catch (Exception e) {
3980                    if (!mInstrumentation.onException(r.activity, e)) {
3981                        throw new RuntimeException(
3982                                "Unable to stop activity "
3983                                + r.intent.getComponent().toShortString()
3984                                + ": " + e.toString(), e);
3985                    }
3986                }
3987                r.stopped = true;
3988                EventLog.writeEvent(LOG_AM_ON_STOP_CALLED, UserHandle.myUserId(),
3989                        r.activity.getComponentName().getClassName(), reason);
3990            }
3991        }
3992    }
3993
3994    private void updateVisibility(ActivityClientRecord r, boolean show) {
3995        View v = r.activity.mDecor;
3996        if (v != null) {
3997            if (show) {
3998                if (!r.activity.mVisibleFromServer) {
3999                    r.activity.mVisibleFromServer = true;
4000                    mNumVisibleActivities++;
4001                    if (r.activity.mVisibleFromClient) {
4002                        r.activity.makeVisible();
4003                    }
4004                }
4005                if (r.newConfig != null) {
4006                    performConfigurationChangedForActivity(r, r.newConfig, REPORT_TO_ACTIVITY);
4007                    if (DEBUG_CONFIGURATION) Slog.v(TAG, "Updating activity vis "
4008                            + r.activityInfo.name + " with new config "
4009                            + r.activity.mCurrentConfig);
4010                    r.newConfig = null;
4011                }
4012            } else {
4013                if (r.activity.mVisibleFromServer) {
4014                    r.activity.mVisibleFromServer = false;
4015                    mNumVisibleActivities--;
4016                    v.setVisibility(View.INVISIBLE);
4017                }
4018            }
4019        }
4020    }
4021
4022    private void handleStopActivity(IBinder token, boolean show, int configChanges, int seq) {
4023        ActivityClientRecord r = mActivities.get(token);
4024        if (!checkAndUpdateLifecycleSeq(seq, r, "stopActivity")) {
4025            return;
4026        }
4027        r.activity.mConfigChangeFlags |= configChanges;
4028
4029        StopInfo info = new StopInfo();
4030        performStopActivityInner(r, info, show, true, "handleStopActivity");
4031
4032        if (localLOGV) Slog.v(
4033            TAG, "Finishing stop of " + r + ": show=" + show
4034            + " win=" + r.window);
4035
4036        updateVisibility(r, show);
4037
4038        // Make sure any pending writes are now committed.
4039        if (!r.isPreHoneycomb()) {
4040            QueuedWork.waitToFinish();
4041        }
4042
4043        // Schedule the call to tell the activity manager we have
4044        // stopped.  We don't do this immediately, because we want to
4045        // have a chance for any other pending work (in particular memory
4046        // trim requests) to complete before you tell the activity
4047        // manager to proceed and allow us to go fully into the background.
4048        info.activity = r;
4049        info.state = r.state;
4050        info.persistentState = r.persistentState;
4051        mH.post(info);
4052        mSomeActivitiesChanged = true;
4053    }
4054
4055    private static boolean checkAndUpdateLifecycleSeq(int seq, ActivityClientRecord r,
4056            String action) {
4057        if (r == null) {
4058            return true;
4059        }
4060        if (seq < r.lastProcessedSeq) {
4061            if (DEBUG_ORDER) Slog.d(TAG, action + " for " + r + " ignored, because seq=" + seq
4062                    + " < mCurrentLifecycleSeq=" + r.lastProcessedSeq);
4063            return false;
4064        }
4065        r.lastProcessedSeq = seq;
4066        return true;
4067    }
4068
4069    final void performRestartActivity(IBinder token) {
4070        ActivityClientRecord r = mActivities.get(token);
4071        if (r.stopped) {
4072            r.activity.performRestart();
4073            r.stopped = false;
4074        }
4075    }
4076
4077    private void handleWindowVisibility(IBinder token, boolean show) {
4078        ActivityClientRecord r = mActivities.get(token);
4079
4080        if (r == null) {
4081            Log.w(TAG, "handleWindowVisibility: no activity for token " + token);
4082            return;
4083        }
4084
4085        if (!show && !r.stopped) {
4086            performStopActivityInner(r, null, show, false, "handleWindowVisibility");
4087        } else if (show && r.stopped) {
4088            // If we are getting ready to gc after going to the background, well
4089            // we are back active so skip it.
4090            unscheduleGcIdler();
4091
4092            r.activity.performRestart();
4093            r.stopped = false;
4094        }
4095        if (r.activity.mDecor != null) {
4096            if (false) Slog.v(
4097                TAG, "Handle window " + r + " visibility: " + show);
4098            updateVisibility(r, show);
4099        }
4100        mSomeActivitiesChanged = true;
4101    }
4102
4103    // TODO: This method should be changed to use {@link #performStopActivityInner} to perform to
4104    // stop operation on the activity to reduce code duplication and the chance of fixing a bug in
4105    // one place and missing the other.
4106    private void handleSleeping(IBinder token, boolean sleeping) {
4107        ActivityClientRecord r = mActivities.get(token);
4108
4109        if (r == null) {
4110            Log.w(TAG, "handleSleeping: no activity for token " + token);
4111            return;
4112        }
4113
4114        if (sleeping) {
4115            if (!r.stopped && !r.isPreHoneycomb()) {
4116                if (!r.activity.mFinished && r.state == null) {
4117                    callCallActivityOnSaveInstanceState(r);
4118                }
4119
4120                try {
4121                    // Now we are idle.
4122                    r.activity.performStop(false /*preserveWindow*/);
4123                } catch (Exception e) {
4124                    if (!mInstrumentation.onException(r.activity, e)) {
4125                        throw new RuntimeException(
4126                                "Unable to stop activity "
4127                                + r.intent.getComponent().toShortString()
4128                                + ": " + e.toString(), e);
4129                    }
4130                }
4131                r.stopped = true;
4132                EventLog.writeEvent(LOG_AM_ON_STOP_CALLED, UserHandle.myUserId(),
4133                        r.activity.getComponentName().getClassName(), "sleeping");
4134            }
4135
4136            // Make sure any pending writes are now committed.
4137            if (!r.isPreHoneycomb()) {
4138                QueuedWork.waitToFinish();
4139            }
4140
4141            // Tell activity manager we slept.
4142            try {
4143                ActivityManager.getService().activitySlept(r.token);
4144            } catch (RemoteException ex) {
4145                throw ex.rethrowFromSystemServer();
4146            }
4147        } else {
4148            if (r.stopped && r.activity.mVisibleFromServer) {
4149                r.activity.performRestart();
4150                r.stopped = false;
4151            }
4152        }
4153    }
4154
4155    private void handleSetCoreSettings(Bundle coreSettings) {
4156        synchronized (mResourcesManager) {
4157            mCoreSettings = coreSettings;
4158        }
4159        onCoreSettingsChange();
4160    }
4161
4162    private void onCoreSettingsChange() {
4163        boolean debugViewAttributes =
4164                mCoreSettings.getInt(Settings.Global.DEBUG_VIEW_ATTRIBUTES, 0) != 0;
4165        if (debugViewAttributes != View.mDebugViewAttributes) {
4166            View.mDebugViewAttributes = debugViewAttributes;
4167
4168            // request all activities to relaunch for the changes to take place
4169            for (Map.Entry<IBinder, ActivityClientRecord> entry : mActivities.entrySet()) {
4170                requestRelaunchActivity(entry.getKey(), null, null, 0, false, null, null, false,
4171                        false /* preserveWindow */);
4172            }
4173        }
4174    }
4175
4176    private void handleUpdatePackageCompatibilityInfo(UpdateCompatibilityData data) {
4177        LoadedApk apk = peekPackageInfo(data.pkg, false);
4178        if (apk != null) {
4179            apk.setCompatibilityInfo(data.info);
4180        }
4181        apk = peekPackageInfo(data.pkg, true);
4182        if (apk != null) {
4183            apk.setCompatibilityInfo(data.info);
4184        }
4185        handleConfigurationChanged(mConfiguration, data.info);
4186        WindowManagerGlobal.getInstance().reportNewConfiguration(mConfiguration);
4187    }
4188
4189    private void deliverResults(ActivityClientRecord r, List<ResultInfo> results) {
4190        final int N = results.size();
4191        for (int i=0; i<N; i++) {
4192            ResultInfo ri = results.get(i);
4193            try {
4194                if (ri.mData != null) {
4195                    ri.mData.setExtrasClassLoader(r.activity.getClassLoader());
4196                    ri.mData.prepareToEnterProcess();
4197                }
4198                if (DEBUG_RESULTS) Slog.v(TAG,
4199                        "Delivering result to activity " + r + " : " + ri);
4200                r.activity.dispatchActivityResult(ri.mResultWho,
4201                        ri.mRequestCode, ri.mResultCode, ri.mData);
4202            } catch (Exception e) {
4203                if (!mInstrumentation.onException(r.activity, e)) {
4204                    throw new RuntimeException(
4205                            "Failure delivering result " + ri + " to activity "
4206                            + r.intent.getComponent().toShortString()
4207                            + ": " + e.toString(), e);
4208                }
4209            }
4210        }
4211    }
4212
4213    private void handleSendResult(ResultData res) {
4214        ActivityClientRecord r = mActivities.get(res.token);
4215        if (DEBUG_RESULTS) Slog.v(TAG, "Handling send result to " + r);
4216        if (r != null) {
4217            final boolean resumed = !r.paused;
4218            if (!r.activity.mFinished && r.activity.mDecor != null
4219                    && r.hideForNow && resumed) {
4220                // We had hidden the activity because it started another
4221                // one...  we have gotten a result back and we are not
4222                // paused, so make sure our window is visible.
4223                updateVisibility(r, true);
4224            }
4225            if (resumed) {
4226                try {
4227                    // Now we are idle.
4228                    r.activity.mCalled = false;
4229                    r.activity.mTemporaryPause = true;
4230                    mInstrumentation.callActivityOnPause(r.activity);
4231                    if (!r.activity.mCalled) {
4232                        throw new SuperNotCalledException(
4233                            "Activity " + r.intent.getComponent().toShortString()
4234                            + " did not call through to super.onPause()");
4235                    }
4236                } catch (SuperNotCalledException e) {
4237                    throw e;
4238                } catch (Exception e) {
4239                    if (!mInstrumentation.onException(r.activity, e)) {
4240                        throw new RuntimeException(
4241                                "Unable to pause activity "
4242                                + r.intent.getComponent().toShortString()
4243                                + ": " + e.toString(), e);
4244                    }
4245                }
4246            }
4247            deliverResults(r, res.results);
4248            if (resumed) {
4249                r.activity.performResume();
4250                r.activity.mTemporaryPause = false;
4251            }
4252        }
4253    }
4254
4255    public final ActivityClientRecord performDestroyActivity(IBinder token, boolean finishing) {
4256        return performDestroyActivity(token, finishing, 0, false);
4257    }
4258
4259    private ActivityClientRecord performDestroyActivity(IBinder token, boolean finishing,
4260            int configChanges, boolean getNonConfigInstance) {
4261        ActivityClientRecord r = mActivities.get(token);
4262        Class<? extends Activity> activityClass = null;
4263        if (localLOGV) Slog.v(TAG, "Performing finish of " + r);
4264        if (r != null) {
4265            activityClass = r.activity.getClass();
4266            r.activity.mConfigChangeFlags |= configChanges;
4267            if (finishing) {
4268                r.activity.mFinished = true;
4269            }
4270
4271            performPauseActivityIfNeeded(r, "destroy");
4272
4273            if (!r.stopped) {
4274                try {
4275                    r.activity.performStop(r.mPreserveWindow);
4276                } catch (SuperNotCalledException e) {
4277                    throw e;
4278                } catch (Exception e) {
4279                    if (!mInstrumentation.onException(r.activity, e)) {
4280                        throw new RuntimeException(
4281                                "Unable to stop activity "
4282                                + safeToComponentShortString(r.intent)
4283                                + ": " + e.toString(), e);
4284                    }
4285                }
4286                r.stopped = true;
4287                EventLog.writeEvent(LOG_AM_ON_STOP_CALLED, UserHandle.myUserId(),
4288                        r.activity.getComponentName().getClassName(), "destroy");
4289            }
4290            if (getNonConfigInstance) {
4291                try {
4292                    r.lastNonConfigurationInstances
4293                            = r.activity.retainNonConfigurationInstances();
4294                } catch (Exception e) {
4295                    if (!mInstrumentation.onException(r.activity, e)) {
4296                        throw new RuntimeException(
4297                                "Unable to retain activity "
4298                                + r.intent.getComponent().toShortString()
4299                                + ": " + e.toString(), e);
4300                    }
4301                }
4302            }
4303            try {
4304                r.activity.mCalled = false;
4305                mInstrumentation.callActivityOnDestroy(r.activity);
4306                if (!r.activity.mCalled) {
4307                    throw new SuperNotCalledException(
4308                        "Activity " + safeToComponentShortString(r.intent) +
4309                        " did not call through to super.onDestroy()");
4310                }
4311                if (r.window != null) {
4312                    r.window.closeAllPanels();
4313                }
4314            } catch (SuperNotCalledException e) {
4315                throw e;
4316            } catch (Exception e) {
4317                if (!mInstrumentation.onException(r.activity, e)) {
4318                    throw new RuntimeException(
4319                            "Unable to destroy activity " + safeToComponentShortString(r.intent)
4320                            + ": " + e.toString(), e);
4321                }
4322            }
4323        }
4324        mActivities.remove(token);
4325        StrictMode.decrementExpectedActivityCount(activityClass);
4326        return r;
4327    }
4328
4329    private static String safeToComponentShortString(Intent intent) {
4330        ComponentName component = intent.getComponent();
4331        return component == null ? "[Unknown]" : component.toShortString();
4332    }
4333
4334    private void handleDestroyActivity(IBinder token, boolean finishing,
4335            int configChanges, boolean getNonConfigInstance) {
4336        ActivityClientRecord r = performDestroyActivity(token, finishing,
4337                configChanges, getNonConfigInstance);
4338        if (r != null) {
4339            cleanUpPendingRemoveWindows(r, finishing);
4340            WindowManager wm = r.activity.getWindowManager();
4341            View v = r.activity.mDecor;
4342            if (v != null) {
4343                if (r.activity.mVisibleFromServer) {
4344                    mNumVisibleActivities--;
4345                }
4346                IBinder wtoken = v.getWindowToken();
4347                if (r.activity.mWindowAdded) {
4348                    if (r.mPreserveWindow) {
4349                        // Hold off on removing this until the new activity's
4350                        // window is being added.
4351                        r.mPendingRemoveWindow = r.window;
4352                        r.mPendingRemoveWindowManager = wm;
4353                        // We can only keep the part of the view hierarchy that we control,
4354                        // everything else must be removed, because it might not be able to
4355                        // behave properly when activity is relaunching.
4356                        r.window.clearContentView();
4357                    } else {
4358                        wm.removeViewImmediate(v);
4359                    }
4360                }
4361                if (wtoken != null && r.mPendingRemoveWindow == null) {
4362                    WindowManagerGlobal.getInstance().closeAll(wtoken,
4363                            r.activity.getClass().getName(), "Activity");
4364                } else if (r.mPendingRemoveWindow != null) {
4365                    // We're preserving only one window, others should be closed so app views
4366                    // will be detached before the final tear down. It should be done now because
4367                    // some components (e.g. WebView) rely on detach callbacks to perform receiver
4368                    // unregister and other cleanup.
4369                    WindowManagerGlobal.getInstance().closeAllExceptView(token, v,
4370                            r.activity.getClass().getName(), "Activity");
4371                }
4372                r.activity.mDecor = null;
4373            }
4374            if (r.mPendingRemoveWindow == null) {
4375                // If we are delaying the removal of the activity window, then
4376                // we can't clean up all windows here.  Note that we can't do
4377                // so later either, which means any windows that aren't closed
4378                // by the app will leak.  Well we try to warning them a lot
4379                // about leaking windows, because that is a bug, so if they are
4380                // using this recreate facility then they get to live with leaks.
4381                WindowManagerGlobal.getInstance().closeAll(token,
4382                        r.activity.getClass().getName(), "Activity");
4383            }
4384
4385            // Mocked out contexts won't be participating in the normal
4386            // process lifecycle, but if we're running with a proper
4387            // ApplicationContext we need to have it tear down things
4388            // cleanly.
4389            Context c = r.activity.getBaseContext();
4390            if (c instanceof ContextImpl) {
4391                ((ContextImpl) c).scheduleFinalCleanup(
4392                        r.activity.getClass().getName(), "Activity");
4393            }
4394        }
4395        if (finishing) {
4396            try {
4397                ActivityManager.getService().activityDestroyed(token);
4398            } catch (RemoteException ex) {
4399                throw ex.rethrowFromSystemServer();
4400            }
4401        }
4402        mSomeActivitiesChanged = true;
4403    }
4404
4405    /**
4406     * @param preserveWindow Whether the activity should try to reuse the window it created,
4407     *                        including the decor view after the relaunch.
4408     */
4409    public final void requestRelaunchActivity(IBinder token,
4410            List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents,
4411            int configChanges, boolean notResumed, Configuration config,
4412            Configuration overrideConfig, boolean fromServer, boolean preserveWindow) {
4413        ActivityClientRecord target = null;
4414
4415        synchronized (mResourcesManager) {
4416            for (int i=0; i<mRelaunchingActivities.size(); i++) {
4417                ActivityClientRecord r = mRelaunchingActivities.get(i);
4418                if (DEBUG_ORDER) Slog.d(TAG, "requestRelaunchActivity: " + this + ", trying: " + r);
4419                if (r.token == token) {
4420                    target = r;
4421                    if (pendingResults != null) {
4422                        if (r.pendingResults != null) {
4423                            r.pendingResults.addAll(pendingResults);
4424                        } else {
4425                            r.pendingResults = pendingResults;
4426                        }
4427                    }
4428                    if (pendingNewIntents != null) {
4429                        if (r.pendingIntents != null) {
4430                            r.pendingIntents.addAll(pendingNewIntents);
4431                        } else {
4432                            r.pendingIntents = pendingNewIntents;
4433                        }
4434                    }
4435
4436                    // For each relaunch request, activity manager expects an answer
4437                    if (!r.onlyLocalRequest && fromServer) {
4438                        try {
4439                            ActivityManager.getService().activityRelaunched(token);
4440                        } catch (RemoteException e) {
4441                            throw e.rethrowFromSystemServer();
4442                        }
4443                    }
4444                    break;
4445                }
4446            }
4447
4448            if (target == null) {
4449                if (DEBUG_ORDER) Slog.d(TAG, "requestRelaunchActivity: target is null, fromServer:"
4450                        + fromServer);
4451                target = new ActivityClientRecord();
4452                target.token = token;
4453                target.pendingResults = pendingResults;
4454                target.pendingIntents = pendingNewIntents;
4455                target.mPreserveWindow = preserveWindow;
4456                if (!fromServer) {
4457                    final ActivityClientRecord existing = mActivities.get(token);
4458                    if (DEBUG_ORDER) Slog.d(TAG, "requestRelaunchActivity: " + existing);
4459                    if (existing != null) {
4460                        if (DEBUG_ORDER) Slog.d(TAG, "requestRelaunchActivity: paused= "
4461                                + existing.paused);;
4462                        target.startsNotResumed = existing.paused;
4463                        target.overrideConfig = existing.overrideConfig;
4464                    }
4465                    target.onlyLocalRequest = true;
4466                }
4467                mRelaunchingActivities.add(target);
4468                sendMessage(H.RELAUNCH_ACTIVITY, target);
4469            }
4470
4471            if (fromServer) {
4472                target.startsNotResumed = notResumed;
4473                target.onlyLocalRequest = false;
4474            }
4475            if (config != null) {
4476                target.createdConfig = config;
4477            }
4478            if (overrideConfig != null) {
4479                target.overrideConfig = overrideConfig;
4480            }
4481            target.pendingConfigChanges |= configChanges;
4482            target.relaunchSeq = getLifecycleSeq();
4483        }
4484        if (DEBUG_ORDER) Slog.d(TAG, "relaunchActivity " + ActivityThread.this + ", target "
4485                + target + " operation received seq: " + target.relaunchSeq);
4486    }
4487
4488    private void handleRelaunchActivity(ActivityClientRecord tmp) {
4489        // If we are getting ready to gc after going to the background, well
4490        // we are back active so skip it.
4491        unscheduleGcIdler();
4492        mSomeActivitiesChanged = true;
4493
4494        Configuration changedConfig = null;
4495        int configChanges = 0;
4496
4497        // First: make sure we have the most recent configuration and most
4498        // recent version of the activity, or skip it if some previous call
4499        // had taken a more recent version.
4500        synchronized (mResourcesManager) {
4501            int N = mRelaunchingActivities.size();
4502            IBinder token = tmp.token;
4503            tmp = null;
4504            for (int i=0; i<N; i++) {
4505                ActivityClientRecord r = mRelaunchingActivities.get(i);
4506                if (r.token == token) {
4507                    tmp = r;
4508                    configChanges |= tmp.pendingConfigChanges;
4509                    mRelaunchingActivities.remove(i);
4510                    i--;
4511                    N--;
4512                }
4513            }
4514
4515            if (tmp == null) {
4516                if (DEBUG_CONFIGURATION) Slog.v(TAG, "Abort, activity not relaunching!");
4517                return;
4518            }
4519
4520            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Relaunching activity "
4521                    + tmp.token + " with configChanges=0x"
4522                    + Integer.toHexString(configChanges));
4523
4524            if (mPendingConfiguration != null) {
4525                changedConfig = mPendingConfiguration;
4526                mPendingConfiguration = null;
4527            }
4528        }
4529
4530        if (tmp.lastProcessedSeq > tmp.relaunchSeq) {
4531            Slog.wtf(TAG, "For some reason target: " + tmp + " has lower sequence: "
4532                    + tmp.relaunchSeq + " than current sequence: " + tmp.lastProcessedSeq);
4533        } else {
4534            tmp.lastProcessedSeq = tmp.relaunchSeq;
4535        }
4536        if (tmp.createdConfig != null) {
4537            // If the activity manager is passing us its current config,
4538            // assume that is really what we want regardless of what we
4539            // may have pending.
4540            if (mConfiguration == null
4541                    || (tmp.createdConfig.isOtherSeqNewer(mConfiguration)
4542                            && mConfiguration.diff(tmp.createdConfig) != 0)) {
4543                if (changedConfig == null
4544                        || tmp.createdConfig.isOtherSeqNewer(changedConfig)) {
4545                    changedConfig = tmp.createdConfig;
4546                }
4547            }
4548        }
4549
4550        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Relaunching activity "
4551                + tmp.token + ": changedConfig=" + changedConfig);
4552
4553        // If there was a pending configuration change, execute it first.
4554        if (changedConfig != null) {
4555            mCurDefaultDisplayDpi = changedConfig.densityDpi;
4556            updateDefaultDensity();
4557            handleConfigurationChanged(changedConfig, null);
4558        }
4559
4560        ActivityClientRecord r = mActivities.get(tmp.token);
4561        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handling relaunch of " + r);
4562        if (r == null) {
4563            if (!tmp.onlyLocalRequest) {
4564                try {
4565                    ActivityManager.getService().activityRelaunched(tmp.token);
4566                } catch (RemoteException e) {
4567                    throw e.rethrowFromSystemServer();
4568                }
4569            }
4570            return;
4571        }
4572
4573        r.activity.mConfigChangeFlags |= configChanges;
4574        r.onlyLocalRequest = tmp.onlyLocalRequest;
4575        r.mPreserveWindow = tmp.mPreserveWindow;
4576        r.lastProcessedSeq = tmp.lastProcessedSeq;
4577        r.relaunchSeq = tmp.relaunchSeq;
4578        Intent currentIntent = r.activity.mIntent;
4579
4580        r.activity.mChangingConfigurations = true;
4581
4582        // If we are preserving the main window across relaunches we would also like to preserve
4583        // the children. However the client side view system does not support preserving
4584        // the child views so we notify the window manager to expect these windows to
4585        // be replaced and defer requests to destroy or hide them. This way we can achieve
4586        // visual continuity. It's important that we do this here prior to pause and destroy
4587        // as that is when we may hide or remove the child views.
4588        //
4589        // There is another scenario, if we have decided locally to relaunch the app from a
4590        // call to recreate, then none of the windows will be prepared for replacement or
4591        // preserved by the server, so we want to notify it that we are preparing to replace
4592        // everything
4593        try {
4594            if (r.mPreserveWindow || r.onlyLocalRequest) {
4595                WindowManagerGlobal.getWindowSession().prepareToReplaceWindows(
4596                        r.token, !r.onlyLocalRequest);
4597            }
4598        } catch (RemoteException e) {
4599            throw e.rethrowFromSystemServer();
4600        }
4601
4602        // Need to ensure state is saved.
4603        if (!r.paused) {
4604            performPauseActivity(r.token, false, r.isPreHoneycomb(), "handleRelaunchActivity");
4605        }
4606        if (r.state == null && !r.stopped && !r.isPreHoneycomb()) {
4607            callCallActivityOnSaveInstanceState(r);
4608        }
4609
4610        handleDestroyActivity(r.token, false, configChanges, true);
4611
4612        r.activity = null;
4613        r.window = null;
4614        r.hideForNow = false;
4615        r.nextIdle = null;
4616        // Merge any pending results and pending intents; don't just replace them
4617        if (tmp.pendingResults != null) {
4618            if (r.pendingResults == null) {
4619                r.pendingResults = tmp.pendingResults;
4620            } else {
4621                r.pendingResults.addAll(tmp.pendingResults);
4622            }
4623        }
4624        if (tmp.pendingIntents != null) {
4625            if (r.pendingIntents == null) {
4626                r.pendingIntents = tmp.pendingIntents;
4627            } else {
4628                r.pendingIntents.addAll(tmp.pendingIntents);
4629            }
4630        }
4631        r.startsNotResumed = tmp.startsNotResumed;
4632        r.overrideConfig = tmp.overrideConfig;
4633
4634        handleLaunchActivity(r, currentIntent, "handleRelaunchActivity");
4635
4636        if (!tmp.onlyLocalRequest) {
4637            try {
4638                ActivityManager.getService().activityRelaunched(r.token);
4639                if (r.window != null) {
4640                    r.window.reportActivityRelaunched();
4641                }
4642            } catch (RemoteException e) {
4643                throw e.rethrowFromSystemServer();
4644            }
4645        }
4646    }
4647
4648    private void callCallActivityOnSaveInstanceState(ActivityClientRecord r) {
4649        r.state = new Bundle();
4650        r.state.setAllowFds(false);
4651        if (r.isPersistable()) {
4652            r.persistentState = new PersistableBundle();
4653            mInstrumentation.callActivityOnSaveInstanceState(r.activity, r.state,
4654                    r.persistentState);
4655        } else {
4656            mInstrumentation.callActivityOnSaveInstanceState(r.activity, r.state);
4657        }
4658    }
4659
4660    ArrayList<ComponentCallbacks2> collectComponentCallbacks(
4661            boolean allActivities, Configuration newConfig) {
4662        ArrayList<ComponentCallbacks2> callbacks
4663                = new ArrayList<ComponentCallbacks2>();
4664
4665        synchronized (mResourcesManager) {
4666            final int NAPP = mAllApplications.size();
4667            for (int i=0; i<NAPP; i++) {
4668                callbacks.add(mAllApplications.get(i));
4669            }
4670            final int NACT = mActivities.size();
4671            for (int i=0; i<NACT; i++) {
4672                ActivityClientRecord ar = mActivities.valueAt(i);
4673                Activity a = ar.activity;
4674                if (a != null) {
4675                    Configuration thisConfig = applyConfigCompatMainThread(
4676                            mCurDefaultDisplayDpi, newConfig,
4677                            ar.packageInfo.getCompatibilityInfo());
4678                    if (!ar.activity.mFinished && (allActivities || !ar.paused)) {
4679                        // If the activity is currently resumed, its configuration
4680                        // needs to change right now.
4681                        callbacks.add(a);
4682                    } else if (thisConfig != null) {
4683                        // Otherwise, we will tell it about the change
4684                        // the next time it is resumed or shown.  Note that
4685                        // the activity manager may, before then, decide the
4686                        // activity needs to be destroyed to handle its new
4687                        // configuration.
4688                        if (DEBUG_CONFIGURATION) {
4689                            Slog.v(TAG, "Setting activity "
4690                                    + ar.activityInfo.name + " newConfig=" + thisConfig);
4691                        }
4692                        ar.newConfig = thisConfig;
4693                    }
4694                }
4695            }
4696            final int NSVC = mServices.size();
4697            for (int i=0; i<NSVC; i++) {
4698                callbacks.add(mServices.valueAt(i));
4699            }
4700        }
4701        synchronized (mProviderMap) {
4702            final int NPRV = mLocalProviders.size();
4703            for (int i=0; i<NPRV; i++) {
4704                callbacks.add(mLocalProviders.valueAt(i).mLocalProvider);
4705            }
4706        }
4707
4708        return callbacks;
4709    }
4710
4711    /**
4712     * Updates the configuration for an Activity. The ActivityClientRecord's
4713     * {@link ActivityClientRecord#overrideConfig} is used to compute the final Configuration for
4714     * that Activity. {@link ActivityClientRecord#tmpConfig} is used as a temporary for delivering
4715     * the updated Configuration.
4716     * @param r ActivityClientRecord representing the Activity.
4717     * @param newBaseConfig The new configuration to use. This may be augmented with
4718     *                      {@link ActivityClientRecord#overrideConfig}.
4719     * @param reportToActivity true if the change should be reported to the Activity's callback.
4720     */
4721    private void performConfigurationChangedForActivity(ActivityClientRecord r,
4722                                                        Configuration newBaseConfig,
4723                                                        boolean reportToActivity) {
4724        r.tmpConfig.setTo(newBaseConfig);
4725        if (r.overrideConfig != null) {
4726            r.tmpConfig.updateFrom(r.overrideConfig);
4727        }
4728        performConfigurationChanged(r.activity, r.token, r.tmpConfig, r.overrideConfig,
4729                reportToActivity);
4730        freeTextLayoutCachesIfNeeded(r.activity.mCurrentConfig.diff(r.tmpConfig));
4731    }
4732
4733    /**
4734     * Creates a new Configuration only if override would modify base. Otherwise returns base.
4735     * @param base The base configuration.
4736     * @param override The update to apply to the base configuration. Can be null.
4737     * @return A Configuration representing base with override applied.
4738     */
4739    private static Configuration createNewConfigAndUpdateIfNotNull(@NonNull Configuration base,
4740            @Nullable Configuration override) {
4741        if (override == null) {
4742            return base;
4743        }
4744        Configuration newConfig = new Configuration(base);
4745        newConfig.updateFrom(override);
4746        return newConfig;
4747    }
4748
4749    /**
4750     * Decides whether to update an Activity's configuration and whether to tell the
4751     * Activity/Component about it.
4752     * @param cb The component callback to notify of configuration change.
4753     * @param activityToken The Activity binder token for which this configuration change happened.
4754     *                      If the change is global, this is null.
4755     * @param newConfig The new configuration.
4756     * @param amOverrideConfig The override config that differentiates the Activity's configuration
4757     *                       from the base global configuration.
4758     *                       This is supplied by ActivityManager.
4759     * @param reportToActivity Notify the Activity of the change.
4760     */
4761    private void performConfigurationChanged(ComponentCallbacks2 cb,
4762                                             IBinder activityToken,
4763                                             Configuration newConfig,
4764                                             Configuration amOverrideConfig,
4765                                             boolean reportToActivity) {
4766        // Only for Activity objects, check that they actually call up to their
4767        // superclass implementation.  ComponentCallbacks2 is an interface, so
4768        // we check the runtime type and act accordingly.
4769        Activity activity = (cb instanceof Activity) ? (Activity) cb : null;
4770        if (activity != null) {
4771            activity.mCalled = false;
4772        }
4773
4774        boolean shouldChangeConfig = false;
4775        if ((activity == null) || (activity.mCurrentConfig == null)) {
4776            shouldChangeConfig = true;
4777        } else {
4778            // If the new config is the same as the config this Activity is already
4779            // running with and the override config also didn't change, then don't
4780            // bother calling onConfigurationChanged.
4781            int diff = activity.mCurrentConfig.diff(newConfig);
4782            if (diff != 0 || !mResourcesManager.isSameResourcesOverrideConfig(activityToken,
4783                    amOverrideConfig)) {
4784                // Always send the task-level config changes. For system-level configuration, if
4785                // this activity doesn't handle any of the config changes, then don't bother
4786                // calling onConfigurationChanged as we're going to destroy it.
4787                if (!mUpdatingSystemConfig
4788                        || (~activity.mActivityInfo.getRealConfigChanged() & diff) == 0
4789                        || !reportToActivity) {
4790                    shouldChangeConfig = true;
4791                }
4792            }
4793        }
4794
4795        if (shouldChangeConfig) {
4796            // Propagate the configuration change to the Activity and ResourcesManager.
4797
4798            // ContextThemeWrappers may override the configuration for that context.
4799            // We must check and apply any overrides defined.
4800            Configuration contextThemeWrapperOverrideConfig = null;
4801            if (cb instanceof ContextThemeWrapper) {
4802                final ContextThemeWrapper contextThemeWrapper = (ContextThemeWrapper) cb;
4803                contextThemeWrapperOverrideConfig = contextThemeWrapper.getOverrideConfiguration();
4804            }
4805
4806            // We only update an Activity's configuration if this is not a global
4807            // configuration change. This must also be done before the callback,
4808            // or else we violate the contract that the new resources are available
4809            // in {@link ComponentCallbacks2#onConfigurationChanged(Configuration)}.
4810            if (activityToken != null) {
4811                // Apply the ContextThemeWrapper override if necessary.
4812                // NOTE: Make sure the configurations are not modified, as they are treated
4813                // as immutable in many places.
4814                final Configuration finalOverrideConfig = createNewConfigAndUpdateIfNotNull(
4815                        amOverrideConfig, contextThemeWrapperOverrideConfig);
4816                mResourcesManager.updateResourcesForActivity(activityToken, finalOverrideConfig);
4817            }
4818
4819            if (reportToActivity) {
4820                // Apply the ContextThemeWrapper override if necessary.
4821                // NOTE: Make sure the configurations are not modified, as they are treated
4822                // as immutable in many places.
4823                final Configuration configToReport = createNewConfigAndUpdateIfNotNull(
4824                        newConfig, contextThemeWrapperOverrideConfig);
4825                cb.onConfigurationChanged(configToReport);
4826            }
4827
4828            if (activity != null) {
4829                if (reportToActivity && !activity.mCalled) {
4830                    throw new SuperNotCalledException(
4831                            "Activity " + activity.getLocalClassName() +
4832                            " did not call through to super.onConfigurationChanged()");
4833                }
4834                activity.mConfigChangeFlags = 0;
4835                activity.mCurrentConfig = new Configuration(newConfig);
4836            }
4837        }
4838    }
4839
4840    public final void applyConfigurationToResources(Configuration config) {
4841        synchronized (mResourcesManager) {
4842            mResourcesManager.applyConfigurationToResourcesLocked(config, null);
4843        }
4844    }
4845
4846    final Configuration applyCompatConfiguration(int displayDensity) {
4847        Configuration config = mConfiguration;
4848        if (mCompatConfiguration == null) {
4849            mCompatConfiguration = new Configuration();
4850        }
4851        mCompatConfiguration.setTo(mConfiguration);
4852        if (mResourcesManager.applyCompatConfigurationLocked(displayDensity,
4853                mCompatConfiguration)) {
4854            config = mCompatConfiguration;
4855        }
4856        return config;
4857    }
4858
4859    final void handleConfigurationChanged(Configuration config, CompatibilityInfo compat) {
4860
4861        int configDiff = 0;
4862
4863        synchronized (mResourcesManager) {
4864            if (mPendingConfiguration != null) {
4865                if (!mPendingConfiguration.isOtherSeqNewer(config)) {
4866                    config = mPendingConfiguration;
4867                    mCurDefaultDisplayDpi = config.densityDpi;
4868                    updateDefaultDensity();
4869                }
4870                mPendingConfiguration = null;
4871            }
4872
4873            if (config == null) {
4874                return;
4875            }
4876
4877            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handle configuration changed: "
4878                    + config);
4879
4880            mResourcesManager.applyConfigurationToResourcesLocked(config, compat);
4881            updateLocaleListFromAppContext(mInitialApplication.getApplicationContext(),
4882                    mResourcesManager.getConfiguration().getLocales());
4883
4884            if (mConfiguration == null) {
4885                mConfiguration = new Configuration();
4886            }
4887            if (!mConfiguration.isOtherSeqNewer(config) && compat == null) {
4888                return;
4889            }
4890
4891            configDiff = mConfiguration.updateFrom(config);
4892            config = applyCompatConfiguration(mCurDefaultDisplayDpi);
4893
4894            final Theme systemTheme = getSystemContext().getTheme();
4895            if ((systemTheme.getChangingConfigurations() & configDiff) != 0) {
4896                systemTheme.rebase();
4897            }
4898        }
4899
4900        ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(false, config);
4901
4902        freeTextLayoutCachesIfNeeded(configDiff);
4903
4904        if (callbacks != null) {
4905            final int N = callbacks.size();
4906            for (int i=0; i<N; i++) {
4907                ComponentCallbacks2 cb = callbacks.get(i);
4908                if (cb instanceof Activity) {
4909                    // If callback is an Activity - call corresponding method to consider override
4910                    // config and avoid onConfigurationChanged if it hasn't changed.
4911                    Activity a = (Activity) cb;
4912                    performConfigurationChangedForActivity(mActivities.get(a.getActivityToken()),
4913                            config, REPORT_TO_ACTIVITY);
4914                } else {
4915                    performConfigurationChanged(cb, null, config, null, REPORT_TO_ACTIVITY);
4916                }
4917            }
4918        }
4919    }
4920
4921    void handleApplicationInfoChanged(@NonNull final ApplicationInfo ai) {
4922        synchronized (mResourcesManager) {
4923            // Update all affected loaded packages with new package information
4924            WeakReference<LoadedApk> ref = mPackages.get(ai.packageName);
4925            LoadedApk apk = ref != null ? ref.get() : null;
4926            if (apk != null) {
4927                apk.updateApplicationInfo(ai, null);
4928            }
4929
4930            ref = mResourcePackages.get(ai.packageName);
4931            apk = ref != null ? ref.get() : null;
4932            if (apk != null) {
4933                apk.updateApplicationInfo(ai, null);
4934            }
4935
4936            // Update all affected Resources objects to use new ResourcesImpl
4937            mResourcesManager.applyNewResourceDirsLocked(ai.sourceDir, ai.resourceDirs);
4938        }
4939
4940        ApplicationPackageManager.configurationChanged();
4941
4942        // Trigger a regular Configuration change event, only with a different assetsSeq number
4943        // so that we actually call through to all components.
4944        Configuration newConfig = new Configuration();
4945        newConfig.unset();
4946        newConfig.assetsSeq = mConfiguration.assetsSeq + 1;
4947        handleConfigurationChanged(newConfig, null);
4948
4949        // Schedule all activities to reload
4950        for (final Map.Entry<IBinder, ActivityClientRecord> entry : mActivities.entrySet()) {
4951            final Activity activity = entry.getValue().activity;
4952            if (!activity.mFinished) {
4953                requestRelaunchActivity(entry.getKey(), null, null, 0, false, null, null, false,
4954                        false);
4955            }
4956        }
4957    }
4958
4959    static void freeTextLayoutCachesIfNeeded(int configDiff) {
4960        if (configDiff != 0) {
4961            // Ask text layout engine to free its caches if there is a locale change
4962            boolean hasLocaleConfigChange = ((configDiff & ActivityInfo.CONFIG_LOCALE) != 0);
4963            if (hasLocaleConfigChange) {
4964                Canvas.freeTextLayoutCaches();
4965                if (DEBUG_CONFIGURATION) Slog.v(TAG, "Cleared TextLayout Caches");
4966            }
4967        }
4968    }
4969
4970    final void handleActivityConfigurationChanged(ActivityConfigChangeData data,
4971            boolean reportToActivity) {
4972        ActivityClientRecord r = mActivities.get(data.activityToken);
4973        if (r == null || r.activity == null) {
4974            return;
4975        }
4976
4977        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handle activity config changed: "
4978                + r.activityInfo.name + ", with callback=" + reportToActivity);
4979
4980        r.overrideConfig = data.overrideConfig;
4981        performConfigurationChangedForActivity(r, mCompatConfiguration, reportToActivity);
4982        mSomeActivitiesChanged = true;
4983    }
4984
4985    final void handleProfilerControl(boolean start, ProfilerInfo profilerInfo, int profileType) {
4986        if (start) {
4987            try {
4988                switch (profileType) {
4989                    default:
4990                        mProfiler.setProfiler(profilerInfo);
4991                        mProfiler.startProfiling();
4992                        break;
4993                }
4994            } catch (RuntimeException e) {
4995                Slog.w(TAG, "Profiling failed on path " + profilerInfo.profileFile
4996                        + " -- can the process access this path?");
4997            } finally {
4998                try {
4999                    profilerInfo.profileFd.close();
5000                } catch (IOException e) {
5001                    Slog.w(TAG, "Failure closing profile fd", e);
5002                }
5003            }
5004        } else {
5005            switch (profileType) {
5006                default:
5007                    mProfiler.stopProfiling();
5008                    break;
5009            }
5010        }
5011    }
5012
5013    /**
5014     * Public entrypoint to stop profiling. This is required to end profiling when the app crashes,
5015     * so that profiler data won't be lost.
5016     *
5017     * @hide
5018     */
5019    public void stopProfiling() {
5020        mProfiler.stopProfiling();
5021    }
5022
5023    static final void handleDumpHeap(boolean managed, DumpHeapData dhd) {
5024        if (managed) {
5025            try {
5026                Debug.dumpHprofData(dhd.path, dhd.fd.getFileDescriptor());
5027            } catch (IOException e) {
5028                Slog.w(TAG, "Managed heap dump failed on path " + dhd.path
5029                        + " -- can the process access this path?");
5030            } finally {
5031                try {
5032                    dhd.fd.close();
5033                } catch (IOException e) {
5034                    Slog.w(TAG, "Failure closing profile fd", e);
5035                }
5036            }
5037        } else {
5038            Debug.dumpNativeHeap(dhd.fd.getFileDescriptor());
5039        }
5040        try {
5041            ActivityManager.getService().dumpHeapFinished(dhd.path);
5042        } catch (RemoteException e) {
5043            throw e.rethrowFromSystemServer();
5044        }
5045    }
5046
5047    final void handleDispatchPackageBroadcast(int cmd, String[] packages) {
5048        boolean hasPkgInfo = false;
5049        switch (cmd) {
5050            case ApplicationThreadConstants.PACKAGE_REMOVED:
5051            case ApplicationThreadConstants.PACKAGE_REMOVED_DONT_KILL:
5052            {
5053                final boolean killApp = cmd == ApplicationThreadConstants.PACKAGE_REMOVED;
5054                if (packages == null) {
5055                    break;
5056                }
5057                synchronized (mResourcesManager) {
5058                    for (int i = packages.length - 1; i >= 0; i--) {
5059                        if (!hasPkgInfo) {
5060                            WeakReference<LoadedApk> ref = mPackages.get(packages[i]);
5061                            if (ref != null && ref.get() != null) {
5062                                hasPkgInfo = true;
5063                            } else {
5064                                ref = mResourcePackages.get(packages[i]);
5065                                if (ref != null && ref.get() != null) {
5066                                    hasPkgInfo = true;
5067                                }
5068                            }
5069                        }
5070                        if (killApp) {
5071                            mPackages.remove(packages[i]);
5072                            mResourcePackages.remove(packages[i]);
5073                        }
5074                    }
5075                }
5076                break;
5077            }
5078            case ApplicationThreadConstants.PACKAGE_REPLACED:
5079            {
5080                if (packages == null) {
5081                    break;
5082                }
5083                synchronized (mResourcesManager) {
5084                    for (int i = packages.length - 1; i >= 0; i--) {
5085                        WeakReference<LoadedApk> ref = mPackages.get(packages[i]);
5086                        LoadedApk pkgInfo = ref != null ? ref.get() : null;
5087                        if (pkgInfo != null) {
5088                            hasPkgInfo = true;
5089                        } else {
5090                            ref = mResourcePackages.get(packages[i]);
5091                            pkgInfo = ref != null ? ref.get() : null;
5092                            if (pkgInfo != null) {
5093                                hasPkgInfo = true;
5094                            }
5095                        }
5096                        // If the package is being replaced, yet it still has a valid
5097                        // LoadedApk object, the package was updated with _DONT_KILL.
5098                        // Adjust it's internal references to the application info and
5099                        // resources.
5100                        if (pkgInfo != null) {
5101                            try {
5102                                final String packageName = packages[i];
5103                                final ApplicationInfo aInfo =
5104                                        sPackageManager.getApplicationInfo(
5105                                                packageName,
5106                                                0 /*flags*/,
5107                                                UserHandle.myUserId());
5108
5109                                if (mActivities.size() > 0) {
5110                                    for (ActivityClientRecord ar : mActivities.values()) {
5111                                        if (ar.activityInfo.applicationInfo.packageName
5112                                                .equals(packageName)) {
5113                                            ar.activityInfo.applicationInfo = aInfo;
5114                                            ar.packageInfo = pkgInfo;
5115                                        }
5116                                    }
5117                                }
5118                                final List<String> oldPaths =
5119                                        sPackageManager.getPreviousCodePaths(packageName);
5120                                pkgInfo.updateApplicationInfo(aInfo, oldPaths);
5121                            } catch (RemoteException e) {
5122                            }
5123                        }
5124                    }
5125                }
5126                break;
5127            }
5128        }
5129        ApplicationPackageManager.handlePackageBroadcast(cmd, packages, hasPkgInfo);
5130    }
5131
5132    final void handleLowMemory() {
5133        ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(true, null);
5134
5135        final int N = callbacks.size();
5136        for (int i=0; i<N; i++) {
5137            callbacks.get(i).onLowMemory();
5138        }
5139
5140        // Ask SQLite to free up as much memory as it can, mostly from its page caches.
5141        if (Process.myUid() != Process.SYSTEM_UID) {
5142            int sqliteReleased = SQLiteDatabase.releaseMemory();
5143            EventLog.writeEvent(SQLITE_MEM_RELEASED_EVENT_LOG_TAG, sqliteReleased);
5144        }
5145
5146        // Ask graphics to free up as much as possible (font/image caches)
5147        Canvas.freeCaches();
5148
5149        // Ask text layout engine to free also as much as possible
5150        Canvas.freeTextLayoutCaches();
5151
5152        BinderInternal.forceGc("mem");
5153    }
5154
5155    final void handleTrimMemory(int level) {
5156        if (DEBUG_MEMORY_TRIM) Slog.v(TAG, "Trimming memory to level: " + level);
5157
5158        ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(true, null);
5159
5160        final int N = callbacks.size();
5161        for (int i = 0; i < N; i++) {
5162            callbacks.get(i).onTrimMemory(level);
5163        }
5164
5165        WindowManagerGlobal.getInstance().trimMemory(level);
5166    }
5167
5168    private void setupGraphicsSupport(Context context, File cacheDir) {
5169        if (Process.isIsolated()) {
5170            // Isolated processes aren't going to do UI.
5171            return;
5172        }
5173        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "setupGraphicsSupport");
5174        try {
5175            int uid = Process.myUid();
5176            String[] packages = getPackageManager().getPackagesForUid(uid);
5177
5178            if (packages != null) {
5179                ThreadedRenderer.setupDiskCache(cacheDir);
5180                RenderScriptCacheDir.setupDiskCache(cacheDir);
5181                GraphicsEnvironment.setupGraphicsEnvironment(context);
5182            }
5183        } catch (RemoteException e) {
5184            throw e.rethrowFromSystemServer();
5185        } finally {
5186            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
5187        }
5188    }
5189
5190    private void updateDefaultDensity() {
5191        final int densityDpi = mCurDefaultDisplayDpi;
5192        if (!mDensityCompatMode
5193                && densityDpi != Configuration.DENSITY_DPI_UNDEFINED
5194                && densityDpi != DisplayMetrics.DENSITY_DEVICE) {
5195            DisplayMetrics.DENSITY_DEVICE = densityDpi;
5196            Bitmap.setDefaultDensity(densityDpi);
5197        }
5198    }
5199
5200    /**
5201     * Returns the correct library directory for the current ABI.
5202     * <p>
5203     * If we're dealing with a multi-arch application that has both 32 and 64 bit shared
5204     * libraries, we might need to choose the secondary depending on what the current
5205     * runtime's instruction set is.
5206     */
5207    private String getInstrumentationLibrary(ApplicationInfo appInfo, InstrumentationInfo insInfo) {
5208        if (appInfo.primaryCpuAbi != null && appInfo.secondaryCpuAbi != null) {
5209            // Get the instruction set supported by the secondary ABI. In the presence
5210            // of a native bridge this might be different than the one secondary ABI used.
5211            String secondaryIsa =
5212                    VMRuntime.getInstructionSet(appInfo.secondaryCpuAbi);
5213            final String secondaryDexCodeIsa =
5214                    SystemProperties.get("ro.dalvik.vm.isa." + secondaryIsa);
5215            secondaryIsa = secondaryDexCodeIsa.isEmpty() ? secondaryIsa : secondaryDexCodeIsa;
5216
5217            final String runtimeIsa = VMRuntime.getRuntime().vmInstructionSet();
5218            if (runtimeIsa.equals(secondaryIsa)) {
5219                return insInfo.secondaryNativeLibraryDir;
5220            }
5221        }
5222        return insInfo.nativeLibraryDir;
5223    }
5224
5225    /**
5226     * The LocaleList set for the app's resources may have been shuffled so that the preferred
5227     * Locale is at position 0. We must find the index of this preferred Locale in the
5228     * original LocaleList.
5229     */
5230    private void updateLocaleListFromAppContext(Context context, LocaleList newLocaleList) {
5231        final Locale bestLocale = context.getResources().getConfiguration().getLocales().get(0);
5232        final int newLocaleListSize = newLocaleList.size();
5233        for (int i = 0; i < newLocaleListSize; i++) {
5234            if (bestLocale.equals(newLocaleList.get(i))) {
5235                LocaleList.setDefault(newLocaleList, i);
5236                return;
5237            }
5238        }
5239
5240        // The app may have overridden the LocaleList with its own Locale
5241        // (not present in the available list). Push the chosen Locale
5242        // to the front of the list.
5243        LocaleList.setDefault(new LocaleList(bestLocale, newLocaleList));
5244    }
5245
5246    private void handleBindApplication(AppBindData data) {
5247        // Register the UI Thread as a sensitive thread to the runtime.
5248        VMRuntime.registerSensitiveThread();
5249        if (data.trackAllocation) {
5250            DdmVmInternal.enableRecentAllocations(true);
5251        }
5252
5253        // Note when this process has started.
5254        Process.setStartTimes(SystemClock.elapsedRealtime(), SystemClock.uptimeMillis());
5255
5256        mBoundApplication = data;
5257        mConfiguration = new Configuration(data.config);
5258        mCompatConfiguration = new Configuration(data.config);
5259
5260        mProfiler = new Profiler();
5261        if (data.initProfilerInfo != null) {
5262            mProfiler.profileFile = data.initProfilerInfo.profileFile;
5263            mProfiler.profileFd = data.initProfilerInfo.profileFd;
5264            mProfiler.samplingInterval = data.initProfilerInfo.samplingInterval;
5265            mProfiler.autoStopProfiler = data.initProfilerInfo.autoStopProfiler;
5266        }
5267
5268        // send up app name; do this *before* waiting for debugger
5269        Process.setArgV0(data.processName);
5270        android.ddm.DdmHandleAppName.setAppName(data.processName,
5271                                                UserHandle.myUserId());
5272
5273        if (data.persistent) {
5274            // Persistent processes on low-memory devices do not get to
5275            // use hardware accelerated drawing, since this can add too much
5276            // overhead to the process.
5277            if (!ActivityManager.isHighEndGfx()) {
5278                ThreadedRenderer.disable(false);
5279            }
5280        }
5281
5282        if (mProfiler.profileFd != null) {
5283            mProfiler.startProfiling();
5284        }
5285
5286        // If the app is Honeycomb MR1 or earlier, switch its AsyncTask
5287        // implementation to use the pool executor.  Normally, we use the
5288        // serialized executor as the default. This has to happen in the
5289        // main thread so the main looper is set right.
5290        if (data.appInfo.targetSdkVersion <= android.os.Build.VERSION_CODES.HONEYCOMB_MR1) {
5291            AsyncTask.setDefaultExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
5292        }
5293
5294        Message.updateCheckRecycle(data.appInfo.targetSdkVersion);
5295
5296        /*
5297         * Before spawning a new process, reset the time zone to be the system time zone.
5298         * This needs to be done because the system time zone could have changed after the
5299         * the spawning of this process. Without doing this this process would have the incorrect
5300         * system time zone.
5301         */
5302        TimeZone.setDefault(null);
5303
5304        /*
5305         * Set the LocaleList. This may change once we create the App Context.
5306         */
5307        LocaleList.setDefault(data.config.getLocales());
5308
5309        synchronized (mResourcesManager) {
5310            /*
5311             * Update the system configuration since its preloaded and might not
5312             * reflect configuration changes. The configuration object passed
5313             * in AppBindData can be safely assumed to be up to date
5314             */
5315            mResourcesManager.applyConfigurationToResourcesLocked(data.config, data.compatInfo);
5316            mCurDefaultDisplayDpi = data.config.densityDpi;
5317
5318            // This calls mResourcesManager so keep it within the synchronized block.
5319            applyCompatConfiguration(mCurDefaultDisplayDpi);
5320        }
5321
5322        data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
5323
5324        /**
5325         * Switch this process to density compatibility mode if needed.
5326         */
5327        if ((data.appInfo.flags&ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES)
5328                == 0) {
5329            mDensityCompatMode = true;
5330            Bitmap.setDefaultDensity(DisplayMetrics.DENSITY_DEFAULT);
5331        }
5332        updateDefaultDensity();
5333
5334        final String use24HourSetting = mCoreSettings.getString(Settings.System.TIME_12_24);
5335        Boolean is24Hr = null;
5336        if (use24HourSetting != null) {
5337            is24Hr = "24".equals(use24HourSetting) ? Boolean.TRUE : Boolean.FALSE;
5338        }
5339        // null : use locale default for 12/24 hour formatting,
5340        // false : use 12 hour format,
5341        // true : use 24 hour format.
5342        DateFormat.set24HourTimePref(is24Hr);
5343
5344        View.mDebugViewAttributes =
5345                mCoreSettings.getInt(Settings.Global.DEBUG_VIEW_ATTRIBUTES, 0) != 0;
5346
5347        /**
5348         * For system applications on userdebug/eng builds, log stack
5349         * traces of disk and network access to dropbox for analysis.
5350         */
5351        if ((data.appInfo.flags &
5352             (ApplicationInfo.FLAG_SYSTEM |
5353              ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0) {
5354            StrictMode.conditionallyEnableDebugLogging();
5355        }
5356
5357        /**
5358         * For apps targetting Honeycomb or later, we don't allow network usage
5359         * on the main event loop / UI thread. This is what ultimately throws
5360         * {@link NetworkOnMainThreadException}.
5361         */
5362        if (data.appInfo.targetSdkVersion >= Build.VERSION_CODES.HONEYCOMB) {
5363            StrictMode.enableDeathOnNetwork();
5364        }
5365
5366        /**
5367         * For apps targetting N or later, we don't allow file:// Uri exposure.
5368         * This is what ultimately throws {@link FileUriExposedException}.
5369         */
5370        if (data.appInfo.targetSdkVersion >= Build.VERSION_CODES.N) {
5371            StrictMode.enableDeathOnFileUriExposure();
5372        }
5373
5374        // We deprecated Build.SERIAL and only apps that target pre NMR1
5375        // SDK can see it. Since access to the serial is now behind a
5376        // permission we push down the value and here we fix it up
5377        // before any app code has been loaded.
5378        try {
5379            Field field = Build.class.getDeclaredField("SERIAL");
5380            field.setAccessible(true);
5381            field.set(Build.class, data.buildSerial);
5382        } catch (NoSuchFieldException | IllegalAccessException e) {
5383            /* ignore */
5384        }
5385
5386        if (data.debugMode != ApplicationThreadConstants.DEBUG_OFF) {
5387            // XXX should have option to change the port.
5388            Debug.changeDebugPort(8100);
5389            if (data.debugMode == ApplicationThreadConstants.DEBUG_WAIT) {
5390                Slog.w(TAG, "Application " + data.info.getPackageName()
5391                      + " is waiting for the debugger on port 8100...");
5392
5393                IActivityManager mgr = ActivityManager.getService();
5394                try {
5395                    mgr.showWaitingForDebugger(mAppThread, true);
5396                } catch (RemoteException ex) {
5397                    throw ex.rethrowFromSystemServer();
5398                }
5399
5400                Debug.waitForDebugger();
5401
5402                try {
5403                    mgr.showWaitingForDebugger(mAppThread, false);
5404                } catch (RemoteException ex) {
5405                    throw ex.rethrowFromSystemServer();
5406                }
5407
5408            } else {
5409                Slog.w(TAG, "Application " + data.info.getPackageName()
5410                      + " can be debugged on port 8100...");
5411            }
5412        }
5413
5414        // Allow application-generated systrace messages if we're debuggable.
5415        boolean isAppDebuggable = (data.appInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
5416        Trace.setAppTracingAllowed(isAppDebuggable);
5417        if (isAppDebuggable && data.enableBinderTracking) {
5418            Binder.enableTracing();
5419        }
5420
5421        /**
5422         * Initialize the default http proxy in this process for the reasons we set the time zone.
5423         */
5424        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Setup proxies");
5425        final IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE);
5426        if (b != null) {
5427            // In pre-boot mode (doing initial launch to collect password), not
5428            // all system is up.  This includes the connectivity service, so don't
5429            // crash if we can't get it.
5430            final IConnectivityManager service = IConnectivityManager.Stub.asInterface(b);
5431            try {
5432                final ProxyInfo proxyInfo = service.getProxyForNetwork(null);
5433                Proxy.setHttpProxySystemProperty(proxyInfo);
5434            } catch (RemoteException e) {
5435                Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
5436                throw e.rethrowFromSystemServer();
5437            }
5438        }
5439        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
5440
5441        // Instrumentation info affects the class loader, so load it before
5442        // setting up the app context.
5443        final InstrumentationInfo ii;
5444        if (data.instrumentationName != null) {
5445            try {
5446                ii = new ApplicationPackageManager(null, getPackageManager())
5447                        .getInstrumentationInfo(data.instrumentationName, 0);
5448            } catch (PackageManager.NameNotFoundException e) {
5449                throw new RuntimeException(
5450                        "Unable to find instrumentation info for: " + data.instrumentationName);
5451            }
5452
5453            mInstrumentationPackageName = ii.packageName;
5454            mInstrumentationAppDir = ii.sourceDir;
5455            mInstrumentationSplitAppDirs = ii.splitSourceDirs;
5456            mInstrumentationLibDir = getInstrumentationLibrary(data.appInfo, ii);
5457            mInstrumentedAppDir = data.info.getAppDir();
5458            mInstrumentedSplitAppDirs = data.info.getSplitAppDirs();
5459            mInstrumentedLibDir = data.info.getLibDir();
5460        } else {
5461            ii = null;
5462        }
5463
5464        final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);
5465        updateLocaleListFromAppContext(appContext,
5466                mResourcesManager.getConfiguration().getLocales());
5467
5468        if (!Process.isIsolated() && !"android".equals(appContext.getPackageName())) {
5469            // This cache location probably points at credential-encrypted
5470            // storage which may not be accessible yet; assign it anyway instead
5471            // of pointing at device-encrypted storage.
5472            final File cacheDir = appContext.getCacheDir();
5473            if (cacheDir != null) {
5474                // Provide a usable directory for temporary files
5475                System.setProperty("java.io.tmpdir", cacheDir.getAbsolutePath());
5476            } else {
5477                Log.v(TAG, "Unable to initialize \"java.io.tmpdir\" property "
5478                        + "due to missing cache directory");
5479            }
5480
5481            // Setup a location to store generated/compiled graphics code.
5482            final Context deviceContext = appContext.createDeviceProtectedStorageContext();
5483            final File codeCacheDir = deviceContext.getCodeCacheDir();
5484            if (codeCacheDir != null) {
5485                setupGraphicsSupport(appContext, codeCacheDir);
5486            } else {
5487                Log.e(TAG, "Unable to setupGraphicsSupport due to missing code-cache directory");
5488            }
5489        }
5490
5491        // Install the Network Security Config Provider. This must happen before the application
5492        // code is loaded to prevent issues with instances of TLS objects being created before
5493        // the provider is installed.
5494        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "NetworkSecurityConfigProvider.install");
5495        NetworkSecurityConfigProvider.install(appContext);
5496        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
5497
5498        // Continue loading instrumentation.
5499        if (ii != null) {
5500            final ApplicationInfo instrApp = new ApplicationInfo();
5501            ii.copyTo(instrApp);
5502            instrApp.initForUser(UserHandle.myUserId());
5503            final LoadedApk pi = getPackageInfo(instrApp, data.compatInfo,
5504                    appContext.getClassLoader(), false, true, false);
5505            final ContextImpl instrContext = ContextImpl.createAppContext(this, pi);
5506
5507            try {
5508                final ClassLoader cl = instrContext.getClassLoader();
5509                mInstrumentation = (Instrumentation)
5510                    cl.loadClass(data.instrumentationName.getClassName()).newInstance();
5511            } catch (Exception e) {
5512                throw new RuntimeException(
5513                    "Unable to instantiate instrumentation "
5514                    + data.instrumentationName + ": " + e.toString(), e);
5515            }
5516
5517            final ComponentName component = new ComponentName(ii.packageName, ii.name);
5518            mInstrumentation.init(this, instrContext, appContext, component,
5519                    data.instrumentationWatcher, data.instrumentationUiAutomationConnection);
5520
5521            if (mProfiler.profileFile != null && !ii.handleProfiling
5522                    && mProfiler.profileFd == null) {
5523                mProfiler.handlingProfiling = true;
5524                final File file = new File(mProfiler.profileFile);
5525                file.getParentFile().mkdirs();
5526                Debug.startMethodTracing(file.toString(), 8 * 1024 * 1024);
5527            }
5528        } else {
5529            mInstrumentation = new Instrumentation();
5530        }
5531
5532        if ((data.appInfo.flags&ApplicationInfo.FLAG_LARGE_HEAP) != 0) {
5533            dalvik.system.VMRuntime.getRuntime().clearGrowthLimit();
5534        } else {
5535            // Small heap, clamp to the current growth limit and let the heap release
5536            // pages after the growth limit to the non growth limit capacity. b/18387825
5537            dalvik.system.VMRuntime.getRuntime().clampGrowthLimit();
5538        }
5539
5540        // Allow disk access during application and provider setup. This could
5541        // block processing ordered broadcasts, but later processing would
5542        // probably end up doing the same disk access.
5543        final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskWrites();
5544        try {
5545            // If the app is being launched for full backup or restore, bring it up in
5546            // a restricted environment with the base application class.
5547            Application app = data.info.makeApplication(data.restrictedBackupMode, null);
5548            mInitialApplication = app;
5549
5550            // don't bring up providers in restricted mode; they may depend on the
5551            // app's custom Application class
5552            if (!data.restrictedBackupMode) {
5553                if (!ArrayUtils.isEmpty(data.providers)) {
5554                    installContentProviders(app, data.providers);
5555                    // For process that contains content providers, we want to
5556                    // ensure that the JIT is enabled "at some point".
5557                    mH.sendEmptyMessageDelayed(H.ENABLE_JIT, 10*1000);
5558                }
5559            }
5560
5561            // Do this after providers, since instrumentation tests generally start their
5562            // test thread at this point, and we don't want that racing.
5563            try {
5564                mInstrumentation.onCreate(data.instrumentationArgs);
5565            }
5566            catch (Exception e) {
5567                throw new RuntimeException(
5568                    "Exception thrown in onCreate() of "
5569                    + data.instrumentationName + ": " + e.toString(), e);
5570            }
5571
5572            try {
5573                mInstrumentation.callApplicationOnCreate(app);
5574            } catch (Exception e) {
5575                if (!mInstrumentation.onException(app, e)) {
5576                    throw new RuntimeException(
5577                        "Unable to create application " + app.getClass().getName()
5578                        + ": " + e.toString(), e);
5579                }
5580            }
5581        } finally {
5582            StrictMode.setThreadPolicy(savedPolicy);
5583        }
5584    }
5585
5586    /*package*/ final void finishInstrumentation(int resultCode, Bundle results) {
5587        IActivityManager am = ActivityManager.getService();
5588        if (mProfiler.profileFile != null && mProfiler.handlingProfiling
5589                && mProfiler.profileFd == null) {
5590            Debug.stopMethodTracing();
5591        }
5592        //Slog.i(TAG, "am: " + ActivityManager.getService()
5593        //      + ", app thr: " + mAppThread);
5594        try {
5595            am.finishInstrumentation(mAppThread, resultCode, results);
5596        } catch (RemoteException ex) {
5597            throw ex.rethrowFromSystemServer();
5598        }
5599    }
5600
5601    private void installContentProviders(
5602            Context context, List<ProviderInfo> providers) {
5603        final ArrayList<ContentProviderHolder> results = new ArrayList<>();
5604
5605        for (ProviderInfo cpi : providers) {
5606            if (DEBUG_PROVIDER) {
5607                StringBuilder buf = new StringBuilder(128);
5608                buf.append("Pub ");
5609                buf.append(cpi.authority);
5610                buf.append(": ");
5611                buf.append(cpi.name);
5612                Log.i(TAG, buf.toString());
5613            }
5614            ContentProviderHolder cph = installProvider(context, null, cpi,
5615                    false /*noisy*/, true /*noReleaseNeeded*/, true /*stable*/);
5616            if (cph != null) {
5617                cph.noReleaseNeeded = true;
5618                results.add(cph);
5619            }
5620        }
5621
5622        try {
5623            ActivityManager.getService().publishContentProviders(
5624                getApplicationThread(), results);
5625        } catch (RemoteException ex) {
5626            throw ex.rethrowFromSystemServer();
5627        }
5628    }
5629
5630    public final IContentProvider acquireProvider(
5631            Context c, String auth, int userId, boolean stable) {
5632        final IContentProvider provider = acquireExistingProvider(c, auth, userId, stable);
5633        if (provider != null) {
5634            return provider;
5635        }
5636
5637        // There is a possible race here.  Another thread may try to acquire
5638        // the same provider at the same time.  When this happens, we want to ensure
5639        // that the first one wins.
5640        // Note that we cannot hold the lock while acquiring and installing the
5641        // provider since it might take a long time to run and it could also potentially
5642        // be re-entrant in the case where the provider is in the same process.
5643        ContentProviderHolder holder = null;
5644        try {
5645            holder = ActivityManager.getService().getContentProvider(
5646                    getApplicationThread(), auth, userId, stable);
5647        } catch (RemoteException ex) {
5648            throw ex.rethrowFromSystemServer();
5649        }
5650        if (holder == null) {
5651            Slog.e(TAG, "Failed to find provider info for " + auth);
5652            return null;
5653        }
5654
5655        // Install provider will increment the reference count for us, and break
5656        // any ties in the race.
5657        holder = installProvider(c, holder, holder.info,
5658                true /*noisy*/, holder.noReleaseNeeded, stable);
5659        return holder.provider;
5660    }
5661
5662    private final void incProviderRefLocked(ProviderRefCount prc, boolean stable) {
5663        if (stable) {
5664            prc.stableCount += 1;
5665            if (prc.stableCount == 1) {
5666                // We are acquiring a new stable reference on the provider.
5667                int unstableDelta;
5668                if (prc.removePending) {
5669                    // We have a pending remove operation, which is holding the
5670                    // last unstable reference.  At this point we are converting
5671                    // that unstable reference to our new stable reference.
5672                    unstableDelta = -1;
5673                    // Cancel the removal of the provider.
5674                    if (DEBUG_PROVIDER) {
5675                        Slog.v(TAG, "incProviderRef: stable "
5676                                + "snatched provider from the jaws of death");
5677                    }
5678                    prc.removePending = false;
5679                    // There is a race! It fails to remove the message, which
5680                    // will be handled in completeRemoveProvider().
5681                    mH.removeMessages(H.REMOVE_PROVIDER, prc);
5682                } else {
5683                    unstableDelta = 0;
5684                }
5685                try {
5686                    if (DEBUG_PROVIDER) {
5687                        Slog.v(TAG, "incProviderRef Now stable - "
5688                                + prc.holder.info.name + ": unstableDelta="
5689                                + unstableDelta);
5690                    }
5691                    ActivityManager.getService().refContentProvider(
5692                            prc.holder.connection, 1, unstableDelta);
5693                } catch (RemoteException e) {
5694                    //do nothing content provider object is dead any way
5695                }
5696            }
5697        } else {
5698            prc.unstableCount += 1;
5699            if (prc.unstableCount == 1) {
5700                // We are acquiring a new unstable reference on the provider.
5701                if (prc.removePending) {
5702                    // Oh look, we actually have a remove pending for the
5703                    // provider, which is still holding the last unstable
5704                    // reference.  We just need to cancel that to take new
5705                    // ownership of the reference.
5706                    if (DEBUG_PROVIDER) {
5707                        Slog.v(TAG, "incProviderRef: unstable "
5708                                + "snatched provider from the jaws of death");
5709                    }
5710                    prc.removePending = false;
5711                    mH.removeMessages(H.REMOVE_PROVIDER, prc);
5712                } else {
5713                    // First unstable ref, increment our count in the
5714                    // activity manager.
5715                    try {
5716                        if (DEBUG_PROVIDER) {
5717                            Slog.v(TAG, "incProviderRef: Now unstable - "
5718                                    + prc.holder.info.name);
5719                        }
5720                        ActivityManager.getService().refContentProvider(
5721                                prc.holder.connection, 0, 1);
5722                    } catch (RemoteException e) {
5723                        //do nothing content provider object is dead any way
5724                    }
5725                }
5726            }
5727        }
5728    }
5729
5730    public final IContentProvider acquireExistingProvider(
5731            Context c, String auth, int userId, boolean stable) {
5732        synchronized (mProviderMap) {
5733            final ProviderKey key = new ProviderKey(auth, userId);
5734            final ProviderClientRecord pr = mProviderMap.get(key);
5735            if (pr == null) {
5736                return null;
5737            }
5738
5739            IContentProvider provider = pr.mProvider;
5740            IBinder jBinder = provider.asBinder();
5741            if (!jBinder.isBinderAlive()) {
5742                // The hosting process of the provider has died; we can't
5743                // use this one.
5744                Log.i(TAG, "Acquiring provider " + auth + " for user " + userId
5745                        + ": existing object's process dead");
5746                handleUnstableProviderDiedLocked(jBinder, true);
5747                return null;
5748            }
5749
5750            // Only increment the ref count if we have one.  If we don't then the
5751            // provider is not reference counted and never needs to be released.
5752            ProviderRefCount prc = mProviderRefCountMap.get(jBinder);
5753            if (prc != null) {
5754                incProviderRefLocked(prc, stable);
5755            }
5756            return provider;
5757        }
5758    }
5759
5760    public final boolean releaseProvider(IContentProvider provider, boolean stable) {
5761        if (provider == null) {
5762            return false;
5763        }
5764
5765        IBinder jBinder = provider.asBinder();
5766        synchronized (mProviderMap) {
5767            ProviderRefCount prc = mProviderRefCountMap.get(jBinder);
5768            if (prc == null) {
5769                // The provider has no ref count, no release is needed.
5770                return false;
5771            }
5772
5773            boolean lastRef = false;
5774            if (stable) {
5775                if (prc.stableCount == 0) {
5776                    if (DEBUG_PROVIDER) Slog.v(TAG,
5777                            "releaseProvider: stable ref count already 0, how?");
5778                    return false;
5779                }
5780                prc.stableCount -= 1;
5781                if (prc.stableCount == 0) {
5782                    // What we do at this point depends on whether there are
5783                    // any unstable refs left: if there are, we just tell the
5784                    // activity manager to decrement its stable count; if there
5785                    // aren't, we need to enqueue this provider to be removed,
5786                    // and convert to holding a single unstable ref while
5787                    // doing so.
5788                    lastRef = prc.unstableCount == 0;
5789                    try {
5790                        if (DEBUG_PROVIDER) {
5791                            Slog.v(TAG, "releaseProvider: No longer stable w/lastRef="
5792                                    + lastRef + " - " + prc.holder.info.name);
5793                        }
5794                        ActivityManager.getService().refContentProvider(
5795                                prc.holder.connection, -1, lastRef ? 1 : 0);
5796                    } catch (RemoteException e) {
5797                        //do nothing content provider object is dead any way
5798                    }
5799                }
5800            } else {
5801                if (prc.unstableCount == 0) {
5802                    if (DEBUG_PROVIDER) Slog.v(TAG,
5803                            "releaseProvider: unstable ref count already 0, how?");
5804                    return false;
5805                }
5806                prc.unstableCount -= 1;
5807                if (prc.unstableCount == 0) {
5808                    // If this is the last reference, we need to enqueue
5809                    // this provider to be removed instead of telling the
5810                    // activity manager to remove it at this point.
5811                    lastRef = prc.stableCount == 0;
5812                    if (!lastRef) {
5813                        try {
5814                            if (DEBUG_PROVIDER) {
5815                                Slog.v(TAG, "releaseProvider: No longer unstable - "
5816                                        + prc.holder.info.name);
5817                            }
5818                            ActivityManager.getService().refContentProvider(
5819                                    prc.holder.connection, 0, -1);
5820                        } catch (RemoteException e) {
5821                            //do nothing content provider object is dead any way
5822                        }
5823                    }
5824                }
5825            }
5826
5827            if (lastRef) {
5828                if (!prc.removePending) {
5829                    // Schedule the actual remove asynchronously, since we don't know the context
5830                    // this will be called in.
5831                    // TODO: it would be nice to post a delayed message, so
5832                    // if we come back and need the same provider quickly
5833                    // we will still have it available.
5834                    if (DEBUG_PROVIDER) {
5835                        Slog.v(TAG, "releaseProvider: Enqueueing pending removal - "
5836                                + prc.holder.info.name);
5837                    }
5838                    prc.removePending = true;
5839                    Message msg = mH.obtainMessage(H.REMOVE_PROVIDER, prc);
5840                    mH.sendMessage(msg);
5841                } else {
5842                    Slog.w(TAG, "Duplicate remove pending of provider " + prc.holder.info.name);
5843                }
5844            }
5845            return true;
5846        }
5847    }
5848
5849    final void completeRemoveProvider(ProviderRefCount prc) {
5850        synchronized (mProviderMap) {
5851            if (!prc.removePending) {
5852                // There was a race!  Some other client managed to acquire
5853                // the provider before the removal was completed.
5854                // Abort the removal.  We will do it later.
5855                if (DEBUG_PROVIDER) Slog.v(TAG, "completeRemoveProvider: lost the race, "
5856                        + "provider still in use");
5857                return;
5858            }
5859
5860            // More complicated race!! Some client managed to acquire the
5861            // provider and release it before the removal was completed.
5862            // Continue the removal, and abort the next remove message.
5863            prc.removePending = false;
5864
5865            final IBinder jBinder = prc.holder.provider.asBinder();
5866            ProviderRefCount existingPrc = mProviderRefCountMap.get(jBinder);
5867            if (existingPrc == prc) {
5868                mProviderRefCountMap.remove(jBinder);
5869            }
5870
5871            for (int i=mProviderMap.size()-1; i>=0; i--) {
5872                ProviderClientRecord pr = mProviderMap.valueAt(i);
5873                IBinder myBinder = pr.mProvider.asBinder();
5874                if (myBinder == jBinder) {
5875                    mProviderMap.removeAt(i);
5876                }
5877            }
5878        }
5879
5880        try {
5881            if (DEBUG_PROVIDER) {
5882                Slog.v(TAG, "removeProvider: Invoking ActivityManagerService."
5883                        + "removeContentProvider(" + prc.holder.info.name + ")");
5884            }
5885            ActivityManager.getService().removeContentProvider(
5886                    prc.holder.connection, false);
5887        } catch (RemoteException e) {
5888            //do nothing content provider object is dead any way
5889        }
5890    }
5891
5892    final void handleUnstableProviderDied(IBinder provider, boolean fromClient) {
5893        synchronized (mProviderMap) {
5894            handleUnstableProviderDiedLocked(provider, fromClient);
5895        }
5896    }
5897
5898    final void handleUnstableProviderDiedLocked(IBinder provider, boolean fromClient) {
5899        ProviderRefCount prc = mProviderRefCountMap.get(provider);
5900        if (prc != null) {
5901            if (DEBUG_PROVIDER) Slog.v(TAG, "Cleaning up dead provider "
5902                    + provider + " " + prc.holder.info.name);
5903            mProviderRefCountMap.remove(provider);
5904            for (int i=mProviderMap.size()-1; i>=0; i--) {
5905                ProviderClientRecord pr = mProviderMap.valueAt(i);
5906                if (pr != null && pr.mProvider.asBinder() == provider) {
5907                    Slog.i(TAG, "Removing dead content provider:" + pr.mProvider.toString());
5908                    mProviderMap.removeAt(i);
5909                }
5910            }
5911
5912            if (fromClient) {
5913                // We found out about this due to execution in our client
5914                // code.  Tell the activity manager about it now, to ensure
5915                // that the next time we go to do anything with the provider
5916                // it knows it is dead (so we don't race with its death
5917                // notification).
5918                try {
5919                    ActivityManager.getService().unstableProviderDied(
5920                            prc.holder.connection);
5921                } catch (RemoteException e) {
5922                    //do nothing content provider object is dead any way
5923                }
5924            }
5925        }
5926    }
5927
5928    final void appNotRespondingViaProvider(IBinder provider) {
5929        synchronized (mProviderMap) {
5930            ProviderRefCount prc = mProviderRefCountMap.get(provider);
5931            if (prc != null) {
5932                try {
5933                    ActivityManager.getService()
5934                            .appNotRespondingViaProvider(prc.holder.connection);
5935                } catch (RemoteException e) {
5936                    throw e.rethrowFromSystemServer();
5937                }
5938            }
5939        }
5940    }
5941
5942    private ProviderClientRecord installProviderAuthoritiesLocked(IContentProvider provider,
5943            ContentProvider localProvider, ContentProviderHolder holder) {
5944        final String auths[] = holder.info.authority.split(";");
5945        final int userId = UserHandle.getUserId(holder.info.applicationInfo.uid);
5946
5947        if (provider != null) {
5948            // If this provider is hosted by the core OS and cannot be upgraded,
5949            // then I guess we're okay doing blocking calls to it.
5950            for (String auth : auths) {
5951                switch (auth) {
5952                    case ContactsContract.AUTHORITY:
5953                    case CallLog.AUTHORITY:
5954                    case CallLog.SHADOW_AUTHORITY:
5955                    case BlockedNumberContract.AUTHORITY:
5956                    case CalendarContract.AUTHORITY:
5957                    case Downloads.Impl.AUTHORITY:
5958                    case "telephony":
5959                        Binder.allowBlocking(provider.asBinder());
5960                }
5961            }
5962        }
5963
5964        final ProviderClientRecord pcr = new ProviderClientRecord(
5965                auths, provider, localProvider, holder);
5966        for (String auth : auths) {
5967            final ProviderKey key = new ProviderKey(auth, userId);
5968            final ProviderClientRecord existing = mProviderMap.get(key);
5969            if (existing != null) {
5970                Slog.w(TAG, "Content provider " + pcr.mHolder.info.name
5971                        + " already published as " + auth);
5972            } else {
5973                mProviderMap.put(key, pcr);
5974            }
5975        }
5976        return pcr;
5977    }
5978
5979    /**
5980     * Installs the provider.
5981     *
5982     * Providers that are local to the process or that come from the system server
5983     * may be installed permanently which is indicated by setting noReleaseNeeded to true.
5984     * Other remote providers are reference counted.  The initial reference count
5985     * for all reference counted providers is one.  Providers that are not reference
5986     * counted do not have a reference count (at all).
5987     *
5988     * This method detects when a provider has already been installed.  When this happens,
5989     * it increments the reference count of the existing provider (if appropriate)
5990     * and returns the existing provider.  This can happen due to concurrent
5991     * attempts to acquire the same provider.
5992     */
5993    private ContentProviderHolder installProvider(Context context,
5994            ContentProviderHolder holder, ProviderInfo info,
5995            boolean noisy, boolean noReleaseNeeded, boolean stable) {
5996        ContentProvider localProvider = null;
5997        IContentProvider provider;
5998        if (holder == null || holder.provider == null) {
5999            if (DEBUG_PROVIDER || noisy) {
6000                Slog.d(TAG, "Loading provider " + info.authority + ": "
6001                        + info.name);
6002            }
6003            Context c = null;
6004            ApplicationInfo ai = info.applicationInfo;
6005            if (context.getPackageName().equals(ai.packageName)) {
6006                c = context;
6007            } else if (mInitialApplication != null &&
6008                    mInitialApplication.getPackageName().equals(ai.packageName)) {
6009                c = mInitialApplication;
6010            } else {
6011                try {
6012                    c = context.createPackageContext(ai.packageName,
6013                            Context.CONTEXT_INCLUDE_CODE);
6014                } catch (PackageManager.NameNotFoundException e) {
6015                    // Ignore
6016                }
6017            }
6018            if (c == null) {
6019                Slog.w(TAG, "Unable to get context for package " +
6020                      ai.packageName +
6021                      " while loading content provider " +
6022                      info.name);
6023                return null;
6024            }
6025            try {
6026                final java.lang.ClassLoader cl = c.getClassLoader();
6027                localProvider = (ContentProvider)cl.
6028                    loadClass(info.name).newInstance();
6029                provider = localProvider.getIContentProvider();
6030                if (provider == null) {
6031                    Slog.e(TAG, "Failed to instantiate class " +
6032                          info.name + " from sourceDir " +
6033                          info.applicationInfo.sourceDir);
6034                    return null;
6035                }
6036                if (DEBUG_PROVIDER) Slog.v(
6037                    TAG, "Instantiating local provider " + info.name);
6038                // XXX Need to create the correct context for this provider.
6039                localProvider.attachInfo(c, info);
6040            } catch (java.lang.Exception e) {
6041                if (!mInstrumentation.onException(null, e)) {
6042                    throw new RuntimeException(
6043                            "Unable to get provider " + info.name
6044                            + ": " + e.toString(), e);
6045                }
6046                return null;
6047            }
6048        } else {
6049            provider = holder.provider;
6050            if (DEBUG_PROVIDER) Slog.v(TAG, "Installing external provider " + info.authority + ": "
6051                    + info.name);
6052        }
6053
6054        ContentProviderHolder retHolder;
6055
6056        synchronized (mProviderMap) {
6057            if (DEBUG_PROVIDER) Slog.v(TAG, "Checking to add " + provider
6058                    + " / " + info.name);
6059            IBinder jBinder = provider.asBinder();
6060            if (localProvider != null) {
6061                ComponentName cname = new ComponentName(info.packageName, info.name);
6062                ProviderClientRecord pr = mLocalProvidersByName.get(cname);
6063                if (pr != null) {
6064                    if (DEBUG_PROVIDER) {
6065                        Slog.v(TAG, "installProvider: lost the race, "
6066                                + "using existing local provider");
6067                    }
6068                    provider = pr.mProvider;
6069                } else {
6070                    holder = new ContentProviderHolder(info);
6071                    holder.provider = provider;
6072                    holder.noReleaseNeeded = true;
6073                    pr = installProviderAuthoritiesLocked(provider, localProvider, holder);
6074                    mLocalProviders.put(jBinder, pr);
6075                    mLocalProvidersByName.put(cname, pr);
6076                }
6077                retHolder = pr.mHolder;
6078            } else {
6079                ProviderRefCount prc = mProviderRefCountMap.get(jBinder);
6080                if (prc != null) {
6081                    if (DEBUG_PROVIDER) {
6082                        Slog.v(TAG, "installProvider: lost the race, updating ref count");
6083                    }
6084                    // We need to transfer our new reference to the existing
6085                    // ref count, releasing the old one...  but only if
6086                    // release is needed (that is, it is not running in the
6087                    // system process).
6088                    if (!noReleaseNeeded) {
6089                        incProviderRefLocked(prc, stable);
6090                        try {
6091                            ActivityManager.getService().removeContentProvider(
6092                                    holder.connection, stable);
6093                        } catch (RemoteException e) {
6094                            //do nothing content provider object is dead any way
6095                        }
6096                    }
6097                } else {
6098                    ProviderClientRecord client = installProviderAuthoritiesLocked(
6099                            provider, localProvider, holder);
6100                    if (noReleaseNeeded) {
6101                        prc = new ProviderRefCount(holder, client, 1000, 1000);
6102                    } else {
6103                        prc = stable
6104                                ? new ProviderRefCount(holder, client, 1, 0)
6105                                : new ProviderRefCount(holder, client, 0, 1);
6106                    }
6107                    mProviderRefCountMap.put(jBinder, prc);
6108                }
6109                retHolder = prc.holder;
6110            }
6111        }
6112        return retHolder;
6113    }
6114
6115    private void attach(boolean system) {
6116        sCurrentActivityThread = this;
6117        mSystemThread = system;
6118        if (!system) {
6119            ViewRootImpl.addFirstDrawHandler(new Runnable() {
6120                @Override
6121                public void run() {
6122                    ensureJitEnabled();
6123                }
6124            });
6125            android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",
6126                                                    UserHandle.myUserId());
6127            RuntimeInit.setApplicationObject(mAppThread.asBinder());
6128            final IActivityManager mgr = ActivityManager.getService();
6129            try {
6130                mgr.attachApplication(mAppThread);
6131            } catch (RemoteException ex) {
6132                throw ex.rethrowFromSystemServer();
6133            }
6134            // Watch for getting close to heap limit.
6135            BinderInternal.addGcWatcher(new Runnable() {
6136                @Override public void run() {
6137                    if (!mSomeActivitiesChanged) {
6138                        return;
6139                    }
6140                    Runtime runtime = Runtime.getRuntime();
6141                    long dalvikMax = runtime.maxMemory();
6142                    long dalvikUsed = runtime.totalMemory() - runtime.freeMemory();
6143                    if (dalvikUsed > ((3*dalvikMax)/4)) {
6144                        if (DEBUG_MEMORY_TRIM) Slog.d(TAG, "Dalvik max=" + (dalvikMax/1024)
6145                                + " total=" + (runtime.totalMemory()/1024)
6146                                + " used=" + (dalvikUsed/1024));
6147                        mSomeActivitiesChanged = false;
6148                        try {
6149                            mgr.releaseSomeActivities(mAppThread);
6150                        } catch (RemoteException e) {
6151                            throw e.rethrowFromSystemServer();
6152                        }
6153                    }
6154                }
6155            });
6156        } else {
6157            // Don't set application object here -- if the system crashes,
6158            // we can't display an alert, we just want to die die die.
6159            android.ddm.DdmHandleAppName.setAppName("system_process",
6160                    UserHandle.myUserId());
6161            try {
6162                mInstrumentation = new Instrumentation();
6163                ContextImpl context = ContextImpl.createAppContext(
6164                        this, getSystemContext().mPackageInfo);
6165                mInitialApplication = context.mPackageInfo.makeApplication(true, null);
6166                mInitialApplication.onCreate();
6167            } catch (Exception e) {
6168                throw new RuntimeException(
6169                        "Unable to instantiate Application():" + e.toString(), e);
6170            }
6171        }
6172
6173        // add dropbox logging to libcore
6174        DropBox.setReporter(new DropBoxReporter());
6175
6176        ViewRootImpl.addConfigCallback(new ComponentCallbacks2() {
6177            @Override
6178            public void onConfigurationChanged(Configuration newConfig) {
6179                synchronized (mResourcesManager) {
6180                    // We need to apply this change to the resources
6181                    // immediately, because upon returning the view
6182                    // hierarchy will be informed about it.
6183                    if (mResourcesManager.applyConfigurationToResourcesLocked(newConfig, null)) {
6184                        updateLocaleListFromAppContext(mInitialApplication.getApplicationContext(),
6185                                mResourcesManager.getConfiguration().getLocales());
6186
6187                        // This actually changed the resources!  Tell
6188                        // everyone about it.
6189                        if (mPendingConfiguration == null ||
6190                                mPendingConfiguration.isOtherSeqNewer(newConfig)) {
6191                            mPendingConfiguration = newConfig;
6192
6193                            sendMessage(H.CONFIGURATION_CHANGED, newConfig);
6194                        }
6195                    }
6196                }
6197            }
6198            @Override
6199            public void onLowMemory() {
6200            }
6201            @Override
6202            public void onTrimMemory(int level) {
6203            }
6204        });
6205    }
6206
6207    public static ActivityThread systemMain() {
6208        // The system process on low-memory devices do not get to use hardware
6209        // accelerated drawing, since this can add too much overhead to the
6210        // process.
6211        if (!ActivityManager.isHighEndGfx()) {
6212            ThreadedRenderer.disable(true);
6213        } else {
6214            ThreadedRenderer.enableForegroundTrimming();
6215        }
6216        ActivityThread thread = new ActivityThread();
6217        thread.attach(true);
6218        return thread;
6219    }
6220
6221    public final void installSystemProviders(List<ProviderInfo> providers) {
6222        if (providers != null) {
6223            installContentProviders(mInitialApplication, providers);
6224        }
6225    }
6226
6227    public int getIntCoreSetting(String key, int defaultValue) {
6228        synchronized (mResourcesManager) {
6229            if (mCoreSettings != null) {
6230                return mCoreSettings.getInt(key, defaultValue);
6231            }
6232            return defaultValue;
6233        }
6234    }
6235
6236    private static class EventLoggingReporter implements EventLogger.Reporter {
6237        @Override
6238        public void report (int code, Object... list) {
6239            EventLog.writeEvent(code, list);
6240        }
6241    }
6242
6243    private class DropBoxReporter implements DropBox.Reporter {
6244
6245        private DropBoxManager dropBox;
6246
6247        public DropBoxReporter() {}
6248
6249        @Override
6250        public void addData(String tag, byte[] data, int flags) {
6251            ensureInitialized();
6252            dropBox.addData(tag, data, flags);
6253        }
6254
6255        @Override
6256        public void addText(String tag, String data) {
6257            ensureInitialized();
6258            dropBox.addText(tag, data);
6259        }
6260
6261        private synchronized void ensureInitialized() {
6262            if (dropBox == null) {
6263                dropBox = (DropBoxManager) getSystemContext().getSystemService(Context.DROPBOX_SERVICE);
6264            }
6265        }
6266    }
6267
6268    public static void main(String[] args) {
6269        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");
6270        SamplingProfilerIntegration.start();
6271
6272        // CloseGuard defaults to true and can be quite spammy.  We
6273        // disable it here, but selectively enable it later (via
6274        // StrictMode) on debug builds, but using DropBox, not logs.
6275        CloseGuard.setEnabled(false);
6276
6277        Environment.initForCurrentUser();
6278
6279        // Set the reporter for event logging in libcore
6280        EventLogger.setReporter(new EventLoggingReporter());
6281
6282        // Make sure TrustedCertificateStore looks in the right place for CA certificates
6283        final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
6284        TrustedCertificateStore.setDefaultUserDirectory(configDir);
6285
6286        Process.setArgV0("<pre-initialized>");
6287
6288        Looper.prepareMainLooper();
6289
6290        ActivityThread thread = new ActivityThread();
6291        thread.attach(false);
6292
6293        if (sMainThreadHandler == null) {
6294            sMainThreadHandler = thread.getHandler();
6295        }
6296
6297        if (false) {
6298            Looper.myLooper().setMessageLogging(new
6299                    LogPrinter(Log.DEBUG, "ActivityThread"));
6300        }
6301
6302        // End of event ActivityThreadMain.
6303        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6304        Looper.loop();
6305
6306        throw new RuntimeException("Main thread loop unexpectedly exited");
6307    }
6308
6309    // ------------------ Regular JNI ------------------------
6310
6311    private native void nDumpGraphicsInfo(FileDescriptor fd);
6312}
6313