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