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