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