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