ActivityThread.java revision 9df97927ab4375fdb589f34cb872355b015aad5a
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                }
3478                if (a.mVisibleFromClient && !a.mWindowAdded) {
3479                    a.mWindowAdded = true;
3480                    wm.addView(decor, l);
3481                }
3482
3483            // If the window has already been added, but during resume
3484            // we started another activity, then don't yet make the
3485            // window visible.
3486            } else if (!willBeVisible) {
3487                if (localLOGV) Slog.v(
3488                    TAG, "Launch " + r + " mStartedActivity set");
3489                r.hideForNow = true;
3490            }
3491
3492            // Get rid of anything left hanging around.
3493            cleanUpPendingRemoveWindows(r, false /* force */);
3494
3495            // The window is now visible if it has been added, we are not
3496            // simply finishing, and we are not starting another activity.
3497            if (!r.activity.mFinished && willBeVisible
3498                    && r.activity.mDecor != null && !r.hideForNow) {
3499                if (r.newConfig != null) {
3500                    performConfigurationChangedForActivity(r, r.newConfig, REPORT_TO_ACTIVITY);
3501                    if (DEBUG_CONFIGURATION) Slog.v(TAG, "Resuming activity "
3502                            + r.activityInfo.name + " with newConfig " + r.activity.mCurrentConfig);
3503                    r.newConfig = null;
3504                }
3505                if (localLOGV) Slog.v(TAG, "Resuming " + r + " with isForward="
3506                        + isForward);
3507                WindowManager.LayoutParams l = r.window.getAttributes();
3508                if ((l.softInputMode
3509                        & WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION)
3510                        != forwardBit) {
3511                    l.softInputMode = (l.softInputMode
3512                            & (~WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION))
3513                            | forwardBit;
3514                    if (r.activity.mVisibleFromClient) {
3515                        ViewManager wm = a.getWindowManager();
3516                        View decor = r.window.getDecorView();
3517                        wm.updateViewLayout(decor, l);
3518                    }
3519                }
3520                r.activity.mVisibleFromServer = true;
3521                mNumVisibleActivities++;
3522                if (r.activity.mVisibleFromClient) {
3523                    r.activity.makeVisible();
3524                }
3525            }
3526
3527            if (!r.onlyLocalRequest) {
3528                r.nextIdle = mNewActivities;
3529                mNewActivities = r;
3530                if (localLOGV) Slog.v(
3531                    TAG, "Scheduling idle handler for " + r);
3532                Looper.myQueue().addIdleHandler(new Idler());
3533            }
3534            r.onlyLocalRequest = false;
3535
3536            // Tell the activity manager we have resumed.
3537            if (reallyResume) {
3538                try {
3539                    ActivityManagerNative.getDefault().activityResumed(token);
3540                } catch (RemoteException ex) {
3541                    throw ex.rethrowFromSystemServer();
3542                }
3543            }
3544
3545        } else {
3546            // If an exception was thrown when trying to resume, then
3547            // just end this activity.
3548            try {
3549                ActivityManagerNative.getDefault()
3550                    .finishActivity(token, Activity.RESULT_CANCELED, null,
3551                            Activity.DONT_FINISH_TASK_WITH_ACTIVITY);
3552            } catch (RemoteException ex) {
3553                throw ex.rethrowFromSystemServer();
3554            }
3555        }
3556    }
3557
3558    private int mThumbnailWidth = -1;
3559    private int mThumbnailHeight = -1;
3560    private Bitmap mAvailThumbnailBitmap = null;
3561    private Canvas mThumbnailCanvas = null;
3562
3563    private Bitmap createThumbnailBitmap(ActivityClientRecord r) {
3564        Bitmap thumbnail = mAvailThumbnailBitmap;
3565        try {
3566            if (thumbnail == null) {
3567                int w = mThumbnailWidth;
3568                int h;
3569                if (w < 0) {
3570                    Resources res = r.activity.getResources();
3571                    int wId = com.android.internal.R.dimen.thumbnail_width;
3572                    int hId = com.android.internal.R.dimen.thumbnail_height;
3573                    mThumbnailWidth = w = res.getDimensionPixelSize(wId);
3574                    mThumbnailHeight = h = res.getDimensionPixelSize(hId);
3575                } else {
3576                    h = mThumbnailHeight;
3577                }
3578
3579                // On platforms where we don't want thumbnails, set dims to (0,0)
3580                if ((w > 0) && (h > 0)) {
3581                    thumbnail = Bitmap.createBitmap(r.activity.getResources().getDisplayMetrics(),
3582                            w, h, THUMBNAIL_FORMAT);
3583                    thumbnail.eraseColor(0);
3584                }
3585            }
3586
3587            if (thumbnail != null) {
3588                Canvas cv = mThumbnailCanvas;
3589                if (cv == null) {
3590                    mThumbnailCanvas = cv = new Canvas();
3591                }
3592
3593                cv.setBitmap(thumbnail);
3594                if (!r.activity.onCreateThumbnail(thumbnail, cv)) {
3595                    mAvailThumbnailBitmap = thumbnail;
3596                    thumbnail = null;
3597                }
3598                cv.setBitmap(null);
3599            }
3600
3601        } catch (Exception e) {
3602            if (!mInstrumentation.onException(r.activity, e)) {
3603                throw new RuntimeException(
3604                        "Unable to create thumbnail of "
3605                        + r.intent.getComponent().toShortString()
3606                        + ": " + e.toString(), e);
3607            }
3608            thumbnail = null;
3609        }
3610
3611        return thumbnail;
3612    }
3613
3614    private void handlePauseActivity(IBinder token, boolean finished,
3615            boolean userLeaving, int configChanges, boolean dontReport, int seq) {
3616        ActivityClientRecord r = mActivities.get(token);
3617        if (DEBUG_ORDER) Slog.d(TAG, "handlePauseActivity " + r + ", seq: " + seq);
3618        if (!checkAndUpdateLifecycleSeq(seq, r, "pauseActivity")) {
3619            return;
3620        }
3621        if (r != null) {
3622            //Slog.v(TAG, "userLeaving=" + userLeaving + " handling pause of " + r);
3623            if (userLeaving) {
3624                performUserLeavingActivity(r);
3625            }
3626
3627            r.activity.mConfigChangeFlags |= configChanges;
3628            performPauseActivity(token, finished, r.isPreHoneycomb(), "handlePauseActivity");
3629
3630            // Make sure any pending writes are now committed.
3631            if (r.isPreHoneycomb()) {
3632                QueuedWork.waitToFinish();
3633            }
3634
3635            // Tell the activity manager we have paused.
3636            if (!dontReport) {
3637                try {
3638                    ActivityManagerNative.getDefault().activityPaused(token);
3639                } catch (RemoteException ex) {
3640                    throw ex.rethrowFromSystemServer();
3641                }
3642            }
3643            mSomeActivitiesChanged = true;
3644        }
3645    }
3646
3647    final void performUserLeavingActivity(ActivityClientRecord r) {
3648        mInstrumentation.callActivityOnUserLeaving(r.activity);
3649    }
3650
3651    final Bundle performPauseActivity(IBinder token, boolean finished,
3652            boolean saveState, String reason) {
3653        ActivityClientRecord r = mActivities.get(token);
3654        return r != null ? performPauseActivity(r, finished, saveState, reason) : null;
3655    }
3656
3657    final Bundle performPauseActivity(ActivityClientRecord r, boolean finished,
3658            boolean saveState, String reason) {
3659        if (r.paused) {
3660            if (r.activity.mFinished) {
3661                // If we are finishing, we won't call onResume() in certain cases.
3662                // So here we likewise don't want to call onPause() if the activity
3663                // isn't resumed.
3664                return null;
3665            }
3666            RuntimeException e = new RuntimeException(
3667                    "Performing pause of activity that is not resumed: "
3668                    + r.intent.getComponent().toShortString());
3669            Slog.e(TAG, e.getMessage(), e);
3670        }
3671        if (finished) {
3672            r.activity.mFinished = true;
3673        }
3674        try {
3675            // Next have the activity save its current state and managed dialogs...
3676            if (!r.activity.mFinished && saveState) {
3677                callCallActivityOnSaveInstanceState(r);
3678            }
3679            // Now we are idle.
3680            r.activity.mCalled = false;
3681            mInstrumentation.callActivityOnPause(r.activity);
3682            EventLog.writeEvent(LOG_AM_ON_PAUSE_CALLED, UserHandle.myUserId(),
3683                    r.activity.getComponentName().getClassName(), reason);
3684            if (!r.activity.mCalled) {
3685                throw new SuperNotCalledException(
3686                    "Activity " + r.intent.getComponent().toShortString() +
3687                    " did not call through to super.onPause()");
3688            }
3689
3690        } catch (SuperNotCalledException e) {
3691            throw e;
3692
3693        } catch (Exception e) {
3694            if (!mInstrumentation.onException(r.activity, e)) {
3695                throw new RuntimeException(
3696                        "Unable to pause activity "
3697                        + r.intent.getComponent().toShortString()
3698                        + ": " + e.toString(), e);
3699            }
3700        }
3701        r.paused = true;
3702
3703        // Notify any outstanding on paused listeners
3704        ArrayList<OnActivityPausedListener> listeners;
3705        synchronized (mOnPauseListeners) {
3706            listeners = mOnPauseListeners.remove(r.activity);
3707        }
3708        int size = (listeners != null ? listeners.size() : 0);
3709        for (int i = 0; i < size; i++) {
3710            listeners.get(i).onPaused(r.activity);
3711        }
3712
3713        return !r.activity.mFinished && saveState ? r.state : null;
3714    }
3715
3716    final void performStopActivity(IBinder token, boolean saveState, String reason) {
3717        ActivityClientRecord r = mActivities.get(token);
3718        performStopActivityInner(r, null, false, saveState, reason);
3719    }
3720
3721    private static class StopInfo implements Runnable {
3722        ActivityClientRecord activity;
3723        Bundle state;
3724        PersistableBundle persistentState;
3725        CharSequence description;
3726
3727        @Override public void run() {
3728            // Tell activity manager we have been stopped.
3729            try {
3730                if (DEBUG_MEMORY_TRIM) Slog.v(TAG, "Reporting activity stopped: " + activity);
3731                ActivityManagerNative.getDefault().activityStopped(
3732                    activity.token, state, persistentState, description);
3733            } catch (RemoteException ex) {
3734                if (ex instanceof TransactionTooLargeException
3735                        && activity.packageInfo.getTargetSdkVersion() < Build.VERSION_CODES.N) {
3736                    Log.e(TAG, "App sent too much data in instance state, so it was ignored", ex);
3737                    return;
3738                }
3739                throw ex.rethrowFromSystemServer();
3740            }
3741        }
3742    }
3743
3744    private static final class ProviderRefCount {
3745        public final IActivityManager.ContentProviderHolder holder;
3746        public final ProviderClientRecord client;
3747        public int stableCount;
3748        public int unstableCount;
3749
3750        // When this is set, the stable and unstable ref counts are 0 and
3751        // we have a pending operation scheduled to remove the ref count
3752        // from the activity manager.  On the activity manager we are still
3753        // holding an unstable ref, though it is not reflected in the counts
3754        // here.
3755        public boolean removePending;
3756
3757        ProviderRefCount(IActivityManager.ContentProviderHolder inHolder,
3758                ProviderClientRecord inClient, int sCount, int uCount) {
3759            holder = inHolder;
3760            client = inClient;
3761            stableCount = sCount;
3762            unstableCount = uCount;
3763        }
3764    }
3765
3766    /**
3767     * Core implementation of stopping an activity.  Note this is a little
3768     * tricky because the server's meaning of stop is slightly different
3769     * than our client -- for the server, stop means to save state and give
3770     * it the result when it is done, but the window may still be visible.
3771     * For the client, we want to call onStop()/onStart() to indicate when
3772     * the activity's UI visibillity changes.
3773     */
3774    private void performStopActivityInner(ActivityClientRecord r,
3775            StopInfo info, boolean keepShown, boolean saveState, String reason) {
3776        if (localLOGV) Slog.v(TAG, "Performing stop of " + r);
3777        if (r != null) {
3778            if (!keepShown && r.stopped) {
3779                if (r.activity.mFinished) {
3780                    // If we are finishing, we won't call onResume() in certain
3781                    // cases.  So here we likewise don't want to call onStop()
3782                    // if the activity isn't resumed.
3783                    return;
3784                }
3785                RuntimeException e = new RuntimeException(
3786                        "Performing stop of activity that is already stopped: "
3787                        + r.intent.getComponent().toShortString());
3788                Slog.e(TAG, e.getMessage(), e);
3789                Slog.e(TAG, r.getStateString());
3790            }
3791
3792            if (info != null) {
3793                try {
3794                    // First create a thumbnail for the activity...
3795                    // For now, don't create the thumbnail here; we are
3796                    // doing that by doing a screen snapshot.
3797                    info.description = r.activity.onCreateDescription();
3798                } catch (Exception e) {
3799                    if (!mInstrumentation.onException(r.activity, e)) {
3800                        throw new RuntimeException(
3801                                "Unable to save state of activity "
3802                                + r.intent.getComponent().toShortString()
3803                                + ": " + e.toString(), e);
3804                    }
3805                }
3806            }
3807
3808            // Next have the activity save its current state and managed dialogs...
3809            if (!r.activity.mFinished && saveState) {
3810                if (r.state == null) {
3811                    callCallActivityOnSaveInstanceState(r);
3812                }
3813            }
3814
3815            if (!keepShown) {
3816                try {
3817                    // Now we are idle.
3818                    r.activity.performStop(false /*preserveWindow*/);
3819                } catch (Exception e) {
3820                    if (!mInstrumentation.onException(r.activity, e)) {
3821                        throw new RuntimeException(
3822                                "Unable to stop activity "
3823                                + r.intent.getComponent().toShortString()
3824                                + ": " + e.toString(), e);
3825                    }
3826                }
3827                r.stopped = true;
3828                EventLog.writeEvent(LOG_AM_ON_STOP_CALLED, UserHandle.myUserId(),
3829                        r.activity.getComponentName().getClassName(), reason);
3830            }
3831
3832            r.paused = true;
3833        }
3834    }
3835
3836    private void updateVisibility(ActivityClientRecord r, boolean show) {
3837        View v = r.activity.mDecor;
3838        if (v != null) {
3839            if (show) {
3840                if (!r.activity.mVisibleFromServer) {
3841                    r.activity.mVisibleFromServer = true;
3842                    mNumVisibleActivities++;
3843                    if (r.activity.mVisibleFromClient) {
3844                        r.activity.makeVisible();
3845                    }
3846                }
3847                if (r.newConfig != null) {
3848                    performConfigurationChangedForActivity(r, r.newConfig, REPORT_TO_ACTIVITY);
3849                    if (DEBUG_CONFIGURATION) Slog.v(TAG, "Updating activity vis "
3850                            + r.activityInfo.name + " with new config "
3851                            + r.activity.mCurrentConfig);
3852                    r.newConfig = null;
3853                }
3854            } else {
3855                if (r.activity.mVisibleFromServer) {
3856                    r.activity.mVisibleFromServer = false;
3857                    mNumVisibleActivities--;
3858                    v.setVisibility(View.INVISIBLE);
3859                }
3860            }
3861        }
3862    }
3863
3864    private void handleStopActivity(IBinder token, boolean show, int configChanges, int seq) {
3865        ActivityClientRecord r = mActivities.get(token);
3866        if (!checkAndUpdateLifecycleSeq(seq, r, "stopActivity")) {
3867            return;
3868        }
3869        r.activity.mConfigChangeFlags |= configChanges;
3870
3871        StopInfo info = new StopInfo();
3872        performStopActivityInner(r, info, show, true, "handleStopActivity");
3873
3874        if (localLOGV) Slog.v(
3875            TAG, "Finishing stop of " + r + ": show=" + show
3876            + " win=" + r.window);
3877
3878        updateVisibility(r, show);
3879
3880        // Make sure any pending writes are now committed.
3881        if (!r.isPreHoneycomb()) {
3882            QueuedWork.waitToFinish();
3883        }
3884
3885        // Schedule the call to tell the activity manager we have
3886        // stopped.  We don't do this immediately, because we want to
3887        // have a chance for any other pending work (in particular memory
3888        // trim requests) to complete before you tell the activity
3889        // manager to proceed and allow us to go fully into the background.
3890        info.activity = r;
3891        info.state = r.state;
3892        info.persistentState = r.persistentState;
3893        mH.post(info);
3894        mSomeActivitiesChanged = true;
3895    }
3896
3897    private static boolean checkAndUpdateLifecycleSeq(int seq, ActivityClientRecord r,
3898            String action) {
3899        if (r == null) {
3900            return true;
3901        }
3902        if (seq < r.lastProcessedSeq) {
3903            if (DEBUG_ORDER) Slog.d(TAG, action + " for " + r + " ignored, because seq=" + seq
3904                    + " < mCurrentLifecycleSeq=" + r.lastProcessedSeq);
3905            return false;
3906        }
3907        r.lastProcessedSeq = seq;
3908        return true;
3909    }
3910
3911    final void performRestartActivity(IBinder token) {
3912        ActivityClientRecord r = mActivities.get(token);
3913        if (r.stopped) {
3914            r.activity.performRestart();
3915            r.stopped = false;
3916        }
3917    }
3918
3919    private void handleWindowVisibility(IBinder token, boolean show) {
3920        ActivityClientRecord r = mActivities.get(token);
3921
3922        if (r == null) {
3923            Log.w(TAG, "handleWindowVisibility: no activity for token " + token);
3924            return;
3925        }
3926
3927        if (!show && !r.stopped) {
3928            performStopActivityInner(r, null, show, false, "handleWindowVisibility");
3929        } else if (show && r.stopped) {
3930            // If we are getting ready to gc after going to the background, well
3931            // we are back active so skip it.
3932            unscheduleGcIdler();
3933
3934            r.activity.performRestart();
3935            r.stopped = false;
3936        }
3937        if (r.activity.mDecor != null) {
3938            if (false) Slog.v(
3939                TAG, "Handle window " + r + " visibility: " + show);
3940            updateVisibility(r, show);
3941        }
3942        mSomeActivitiesChanged = true;
3943    }
3944
3945    private void handleSleeping(IBinder token, boolean sleeping) {
3946        ActivityClientRecord r = mActivities.get(token);
3947
3948        if (r == null) {
3949            Log.w(TAG, "handleSleeping: no activity for token " + token);
3950            return;
3951        }
3952
3953        if (sleeping) {
3954            if (!r.stopped && !r.isPreHoneycomb()) {
3955                try {
3956                    // Now we are idle.
3957                    r.activity.performStop(false /*preserveWindow*/);
3958                } catch (Exception e) {
3959                    if (!mInstrumentation.onException(r.activity, e)) {
3960                        throw new RuntimeException(
3961                                "Unable to stop activity "
3962                                + r.intent.getComponent().toShortString()
3963                                + ": " + e.toString(), e);
3964                    }
3965                }
3966                r.stopped = true;
3967                EventLog.writeEvent(LOG_AM_ON_STOP_CALLED, UserHandle.myUserId(),
3968                        r.activity.getComponentName().getClassName(), "sleeping");
3969            }
3970
3971            // Make sure any pending writes are now committed.
3972            if (!r.isPreHoneycomb()) {
3973                QueuedWork.waitToFinish();
3974            }
3975
3976            // Tell activity manager we slept.
3977            try {
3978                ActivityManagerNative.getDefault().activitySlept(r.token);
3979            } catch (RemoteException ex) {
3980                throw ex.rethrowFromSystemServer();
3981            }
3982        } else {
3983            if (r.stopped && r.activity.mVisibleFromServer) {
3984                r.activity.performRestart();
3985                r.stopped = false;
3986            }
3987        }
3988    }
3989
3990    private void handleSetCoreSettings(Bundle coreSettings) {
3991        synchronized (mResourcesManager) {
3992            mCoreSettings = coreSettings;
3993        }
3994        onCoreSettingsChange();
3995    }
3996
3997    private void onCoreSettingsChange() {
3998        boolean debugViewAttributes =
3999                mCoreSettings.getInt(Settings.Global.DEBUG_VIEW_ATTRIBUTES, 0) != 0;
4000        if (debugViewAttributes != View.mDebugViewAttributes) {
4001            View.mDebugViewAttributes = debugViewAttributes;
4002
4003            // request all activities to relaunch for the changes to take place
4004            for (Map.Entry<IBinder, ActivityClientRecord> entry : mActivities.entrySet()) {
4005                requestRelaunchActivity(entry.getKey(), null, null, 0, false, null, null, false,
4006                        false /* preserveWindow */);
4007            }
4008        }
4009    }
4010
4011    private void handleUpdatePackageCompatibilityInfo(UpdateCompatibilityData data) {
4012        LoadedApk apk = peekPackageInfo(data.pkg, false);
4013        if (apk != null) {
4014            apk.setCompatibilityInfo(data.info);
4015        }
4016        apk = peekPackageInfo(data.pkg, true);
4017        if (apk != null) {
4018            apk.setCompatibilityInfo(data.info);
4019        }
4020        handleConfigurationChanged(mConfiguration, data.info);
4021        WindowManagerGlobal.getInstance().reportNewConfiguration(mConfiguration);
4022    }
4023
4024    private void deliverResults(ActivityClientRecord r, List<ResultInfo> results) {
4025        final int N = results.size();
4026        for (int i=0; i<N; i++) {
4027            ResultInfo ri = results.get(i);
4028            try {
4029                if (ri.mData != null) {
4030                    ri.mData.setExtrasClassLoader(r.activity.getClassLoader());
4031                    ri.mData.prepareToEnterProcess();
4032                }
4033                if (DEBUG_RESULTS) Slog.v(TAG,
4034                        "Delivering result to activity " + r + " : " + ri);
4035                r.activity.dispatchActivityResult(ri.mResultWho,
4036                        ri.mRequestCode, ri.mResultCode, ri.mData);
4037            } catch (Exception e) {
4038                if (!mInstrumentation.onException(r.activity, e)) {
4039                    throw new RuntimeException(
4040                            "Failure delivering result " + ri + " to activity "
4041                            + r.intent.getComponent().toShortString()
4042                            + ": " + e.toString(), e);
4043                }
4044            }
4045        }
4046    }
4047
4048    private void handleSendResult(ResultData res) {
4049        ActivityClientRecord r = mActivities.get(res.token);
4050        if (DEBUG_RESULTS) Slog.v(TAG, "Handling send result to " + r);
4051        if (r != null) {
4052            final boolean resumed = !r.paused;
4053            if (!r.activity.mFinished && r.activity.mDecor != null
4054                    && r.hideForNow && resumed) {
4055                // We had hidden the activity because it started another
4056                // one...  we have gotten a result back and we are not
4057                // paused, so make sure our window is visible.
4058                updateVisibility(r, true);
4059            }
4060            if (resumed) {
4061                try {
4062                    // Now we are idle.
4063                    r.activity.mCalled = false;
4064                    r.activity.mTemporaryPause = true;
4065                    mInstrumentation.callActivityOnPause(r.activity);
4066                    if (!r.activity.mCalled) {
4067                        throw new SuperNotCalledException(
4068                            "Activity " + r.intent.getComponent().toShortString()
4069                            + " did not call through to super.onPause()");
4070                    }
4071                } catch (SuperNotCalledException e) {
4072                    throw e;
4073                } catch (Exception e) {
4074                    if (!mInstrumentation.onException(r.activity, e)) {
4075                        throw new RuntimeException(
4076                                "Unable to pause activity "
4077                                + r.intent.getComponent().toShortString()
4078                                + ": " + e.toString(), e);
4079                    }
4080                }
4081            }
4082            deliverResults(r, res.results);
4083            if (resumed) {
4084                r.activity.performResume();
4085                r.activity.mTemporaryPause = false;
4086            }
4087        }
4088    }
4089
4090    public final ActivityClientRecord performDestroyActivity(IBinder token, boolean finishing) {
4091        return performDestroyActivity(token, finishing, 0, false);
4092    }
4093
4094    private ActivityClientRecord performDestroyActivity(IBinder token, boolean finishing,
4095            int configChanges, boolean getNonConfigInstance) {
4096        ActivityClientRecord r = mActivities.get(token);
4097        Class<? extends Activity> activityClass = null;
4098        if (localLOGV) Slog.v(TAG, "Performing finish of " + r);
4099        if (r != null) {
4100            activityClass = r.activity.getClass();
4101            r.activity.mConfigChangeFlags |= configChanges;
4102            if (finishing) {
4103                r.activity.mFinished = true;
4104            }
4105            if (!r.paused) {
4106                try {
4107                    r.activity.mCalled = false;
4108                    mInstrumentation.callActivityOnPause(r.activity);
4109                    EventLog.writeEvent(LOG_AM_ON_PAUSE_CALLED, UserHandle.myUserId(),
4110                            r.activity.getComponentName().getClassName(), "destroy");
4111                    if (!r.activity.mCalled) {
4112                        throw new SuperNotCalledException(
4113                            "Activity " + safeToComponentShortString(r.intent)
4114                            + " did not call through to super.onPause()");
4115                    }
4116                } catch (SuperNotCalledException e) {
4117                    throw e;
4118                } catch (Exception e) {
4119                    if (!mInstrumentation.onException(r.activity, e)) {
4120                        throw new RuntimeException(
4121                                "Unable to pause activity "
4122                                + safeToComponentShortString(r.intent)
4123                                + ": " + e.toString(), e);
4124                    }
4125                }
4126                r.paused = true;
4127            }
4128            if (!r.stopped) {
4129                try {
4130                    r.activity.performStop(r.mPreserveWindow);
4131                } catch (SuperNotCalledException e) {
4132                    throw e;
4133                } catch (Exception e) {
4134                    if (!mInstrumentation.onException(r.activity, e)) {
4135                        throw new RuntimeException(
4136                                "Unable to stop activity "
4137                                + safeToComponentShortString(r.intent)
4138                                + ": " + e.toString(), e);
4139                    }
4140                }
4141                r.stopped = true;
4142                EventLog.writeEvent(LOG_AM_ON_STOP_CALLED, UserHandle.myUserId(),
4143                        r.activity.getComponentName().getClassName(), "destroy");
4144            }
4145            if (getNonConfigInstance) {
4146                try {
4147                    r.lastNonConfigurationInstances
4148                            = r.activity.retainNonConfigurationInstances();
4149                } catch (Exception e) {
4150                    if (!mInstrumentation.onException(r.activity, e)) {
4151                        throw new RuntimeException(
4152                                "Unable to retain activity "
4153                                + r.intent.getComponent().toShortString()
4154                                + ": " + e.toString(), e);
4155                    }
4156                }
4157            }
4158            try {
4159                r.activity.mCalled = false;
4160                mInstrumentation.callActivityOnDestroy(r.activity);
4161                if (!r.activity.mCalled) {
4162                    throw new SuperNotCalledException(
4163                        "Activity " + safeToComponentShortString(r.intent) +
4164                        " did not call through to super.onDestroy()");
4165                }
4166                if (r.window != null) {
4167                    r.window.closeAllPanels();
4168                }
4169            } catch (SuperNotCalledException e) {
4170                throw e;
4171            } catch (Exception e) {
4172                if (!mInstrumentation.onException(r.activity, e)) {
4173                    throw new RuntimeException(
4174                            "Unable to destroy activity " + safeToComponentShortString(r.intent)
4175                            + ": " + e.toString(), e);
4176                }
4177            }
4178        }
4179        mActivities.remove(token);
4180        StrictMode.decrementExpectedActivityCount(activityClass);
4181        return r;
4182    }
4183
4184    private static String safeToComponentShortString(Intent intent) {
4185        ComponentName component = intent.getComponent();
4186        return component == null ? "[Unknown]" : component.toShortString();
4187    }
4188
4189    private void handleDestroyActivity(IBinder token, boolean finishing,
4190            int configChanges, boolean getNonConfigInstance) {
4191        ActivityClientRecord r = performDestroyActivity(token, finishing,
4192                configChanges, getNonConfigInstance);
4193        if (r != null) {
4194            cleanUpPendingRemoveWindows(r, finishing);
4195            WindowManager wm = r.activity.getWindowManager();
4196            View v = r.activity.mDecor;
4197            if (v != null) {
4198                if (r.activity.mVisibleFromServer) {
4199                    mNumVisibleActivities--;
4200                }
4201                IBinder wtoken = v.getWindowToken();
4202                if (r.activity.mWindowAdded) {
4203                    if (r.onlyLocalRequest || r.mPreserveWindow) {
4204                        // Hold off on removing this until the new activity's
4205                        // window is being added.
4206                        r.mPendingRemoveWindow = r.window;
4207                        r.mPendingRemoveWindowManager = wm;
4208                        if (r.mPreserveWindow) {
4209                            // We can only keep the part of the view hierarchy that we control,
4210                            // everything else must be removed, because it might not be able to
4211                            // behave properly when activity is relaunching.
4212                            r.window.clearContentView();
4213                        }
4214                    } else {
4215                        wm.removeViewImmediate(v);
4216                    }
4217                }
4218                if (wtoken != null && r.mPendingRemoveWindow == null) {
4219                    WindowManagerGlobal.getInstance().closeAll(wtoken,
4220                            r.activity.getClass().getName(), "Activity");
4221                }
4222                r.activity.mDecor = null;
4223            }
4224            if (r.mPendingRemoveWindow == null) {
4225                // If we are delaying the removal of the activity window, then
4226                // we can't clean up all windows here.  Note that we can't do
4227                // so later either, which means any windows that aren't closed
4228                // by the app will leak.  Well we try to warning them a lot
4229                // about leaking windows, because that is a bug, so if they are
4230                // using this recreate facility then they get to live with leaks.
4231                WindowManagerGlobal.getInstance().closeAll(token,
4232                        r.activity.getClass().getName(), "Activity");
4233            }
4234
4235            // Mocked out contexts won't be participating in the normal
4236            // process lifecycle, but if we're running with a proper
4237            // ApplicationContext we need to have it tear down things
4238            // cleanly.
4239            Context c = r.activity.getBaseContext();
4240            if (c instanceof ContextImpl) {
4241                ((ContextImpl) c).scheduleFinalCleanup(
4242                        r.activity.getClass().getName(), "Activity");
4243            }
4244        }
4245        if (finishing) {
4246            try {
4247                ActivityManagerNative.getDefault().activityDestroyed(token);
4248            } catch (RemoteException ex) {
4249                throw ex.rethrowFromSystemServer();
4250            }
4251        }
4252        mSomeActivitiesChanged = true;
4253    }
4254
4255    /**
4256     * @param preserveWindow Whether the activity should try to reuse the window it created,
4257     *                        including the decor view after the relaunch.
4258     */
4259    public final void requestRelaunchActivity(IBinder token,
4260            List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents,
4261            int configChanges, boolean notResumed, Configuration config,
4262            Configuration overrideConfig, boolean fromServer, boolean preserveWindow) {
4263        ActivityClientRecord target = null;
4264
4265        synchronized (mResourcesManager) {
4266            for (int i=0; i<mRelaunchingActivities.size(); i++) {
4267                ActivityClientRecord r = mRelaunchingActivities.get(i);
4268                if (DEBUG_ORDER) Slog.d(TAG, "requestRelaunchActivity: " + this + ", trying: " + r);
4269                if (r.token == token) {
4270                    target = r;
4271                    if (pendingResults != null) {
4272                        if (r.pendingResults != null) {
4273                            r.pendingResults.addAll(pendingResults);
4274                        } else {
4275                            r.pendingResults = pendingResults;
4276                        }
4277                    }
4278                    if (pendingNewIntents != null) {
4279                        if (r.pendingIntents != null) {
4280                            r.pendingIntents.addAll(pendingNewIntents);
4281                        } else {
4282                            r.pendingIntents = pendingNewIntents;
4283                        }
4284                    }
4285
4286                    // For each relaunch request, activity manager expects an answer
4287                    if (!r.onlyLocalRequest && fromServer) {
4288                        try {
4289                            ActivityManagerNative.getDefault().activityRelaunched(token);
4290                        } catch (RemoteException e) {
4291                            throw e.rethrowFromSystemServer();
4292                        }
4293                    }
4294                    break;
4295                }
4296            }
4297
4298            if (target == null) {
4299                if (DEBUG_ORDER) Slog.d(TAG, "requestRelaunchActivity: target is null, fromServer:"
4300                        + fromServer);
4301                target = new ActivityClientRecord();
4302                target.token = token;
4303                target.pendingResults = pendingResults;
4304                target.pendingIntents = pendingNewIntents;
4305                target.mPreserveWindow = preserveWindow;
4306                if (!fromServer) {
4307                    final ActivityClientRecord existing = mActivities.get(token);
4308                    if (DEBUG_ORDER) Slog.d(TAG, "requestRelaunchActivity: " + existing);
4309                    if (existing != null) {
4310                        if (DEBUG_ORDER) Slog.d(TAG, "requestRelaunchActivity: paused= "
4311                                + existing.paused);;
4312                        target.startsNotResumed = existing.paused;
4313                        target.overrideConfig = existing.overrideConfig;
4314                    }
4315                    target.onlyLocalRequest = true;
4316                }
4317                mRelaunchingActivities.add(target);
4318                sendMessage(H.RELAUNCH_ACTIVITY, target);
4319            }
4320
4321            if (fromServer) {
4322                target.startsNotResumed = notResumed;
4323                target.onlyLocalRequest = false;
4324            }
4325            if (config != null) {
4326                target.createdConfig = config;
4327            }
4328            if (overrideConfig != null) {
4329                target.overrideConfig = overrideConfig;
4330            }
4331            target.pendingConfigChanges |= configChanges;
4332            target.relaunchSeq = getLifecycleSeq();
4333        }
4334        if (DEBUG_ORDER) Slog.d(TAG, "relaunchActivity " + ActivityThread.this + ", target "
4335                + target + " operation received seq: " + target.relaunchSeq);
4336    }
4337
4338    private void handleRelaunchActivity(ActivityClientRecord tmp) {
4339        // If we are getting ready to gc after going to the background, well
4340        // we are back active so skip it.
4341        unscheduleGcIdler();
4342        mSomeActivitiesChanged = true;
4343
4344        Configuration changedConfig = null;
4345        int configChanges = 0;
4346
4347        // First: make sure we have the most recent configuration and most
4348        // recent version of the activity, or skip it if some previous call
4349        // had taken a more recent version.
4350        synchronized (mResourcesManager) {
4351            int N = mRelaunchingActivities.size();
4352            IBinder token = tmp.token;
4353            tmp = null;
4354            for (int i=0; i<N; i++) {
4355                ActivityClientRecord r = mRelaunchingActivities.get(i);
4356                if (r.token == token) {
4357                    tmp = r;
4358                    configChanges |= tmp.pendingConfigChanges;
4359                    mRelaunchingActivities.remove(i);
4360                    i--;
4361                    N--;
4362                }
4363            }
4364
4365            if (tmp == null) {
4366                if (DEBUG_CONFIGURATION) Slog.v(TAG, "Abort, activity not relaunching!");
4367                return;
4368            }
4369
4370            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Relaunching activity "
4371                    + tmp.token + " with configChanges=0x"
4372                    + Integer.toHexString(configChanges));
4373
4374            if (mPendingConfiguration != null) {
4375                changedConfig = mPendingConfiguration;
4376                mPendingConfiguration = null;
4377            }
4378        }
4379
4380        if (tmp.lastProcessedSeq > tmp.relaunchSeq) {
4381            Slog.wtf(TAG, "For some reason target: " + tmp + " has lower sequence: "
4382                    + tmp.relaunchSeq + " than current sequence: " + tmp.lastProcessedSeq);
4383        } else {
4384            tmp.lastProcessedSeq = tmp.relaunchSeq;
4385        }
4386        if (tmp.createdConfig != null) {
4387            // If the activity manager is passing us its current config,
4388            // assume that is really what we want regardless of what we
4389            // may have pending.
4390            if (mConfiguration == null
4391                    || (tmp.createdConfig.isOtherSeqNewer(mConfiguration)
4392                            && mConfiguration.diff(tmp.createdConfig) != 0)) {
4393                if (changedConfig == null
4394                        || tmp.createdConfig.isOtherSeqNewer(changedConfig)) {
4395                    changedConfig = tmp.createdConfig;
4396                }
4397            }
4398        }
4399
4400        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Relaunching activity "
4401                + tmp.token + ": changedConfig=" + changedConfig);
4402
4403        // If there was a pending configuration change, execute it first.
4404        if (changedConfig != null) {
4405            mCurDefaultDisplayDpi = changedConfig.densityDpi;
4406            updateDefaultDensity();
4407            handleConfigurationChanged(changedConfig, null);
4408        }
4409
4410        ActivityClientRecord r = mActivities.get(tmp.token);
4411        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handling relaunch of " + r);
4412        if (r == null) {
4413            if (!tmp.onlyLocalRequest) {
4414                try {
4415                    ActivityManagerNative.getDefault().activityRelaunched(tmp.token);
4416                } catch (RemoteException e) {
4417                    throw e.rethrowFromSystemServer();
4418                }
4419            }
4420            return;
4421        }
4422
4423        r.activity.mConfigChangeFlags |= configChanges;
4424        r.onlyLocalRequest = tmp.onlyLocalRequest;
4425        r.mPreserveWindow = tmp.mPreserveWindow;
4426        r.lastProcessedSeq = tmp.lastProcessedSeq;
4427        r.relaunchSeq = tmp.relaunchSeq;
4428        Intent currentIntent = r.activity.mIntent;
4429
4430        r.activity.mChangingConfigurations = true;
4431
4432        // If we are preserving the main window across relaunches we would also like to preserve
4433        // the children. However the client side view system does not support preserving
4434        // the child views so we notify the window manager to expect these windows to
4435        // be replaced and defer requests to destroy or hide them. This way we can achieve
4436        // visual continuity. It's important that we do this here prior to pause and destroy
4437        // as that is when we may hide or remove the child views.
4438        try {
4439            if (r.mPreserveWindow) {
4440                WindowManagerGlobal.getWindowSession().prepareToReplaceChildren(r.token);
4441            }
4442        } catch (RemoteException e) {
4443            throw e.rethrowFromSystemServer();
4444        }
4445
4446
4447        // Need to ensure state is saved.
4448        if (!r.paused) {
4449            performPauseActivity(r.token, false, r.isPreHoneycomb(), "handleRelaunchActivity");
4450        }
4451        if (r.state == null && !r.stopped && !r.isPreHoneycomb()) {
4452            callCallActivityOnSaveInstanceState(r);
4453        }
4454
4455        handleDestroyActivity(r.token, false, configChanges, true);
4456
4457        r.activity = null;
4458        r.window = null;
4459        r.hideForNow = false;
4460        r.nextIdle = null;
4461        // Merge any pending results and pending intents; don't just replace them
4462        if (tmp.pendingResults != null) {
4463            if (r.pendingResults == null) {
4464                r.pendingResults = tmp.pendingResults;
4465            } else {
4466                r.pendingResults.addAll(tmp.pendingResults);
4467            }
4468        }
4469        if (tmp.pendingIntents != null) {
4470            if (r.pendingIntents == null) {
4471                r.pendingIntents = tmp.pendingIntents;
4472            } else {
4473                r.pendingIntents.addAll(tmp.pendingIntents);
4474            }
4475        }
4476        r.startsNotResumed = tmp.startsNotResumed;
4477        r.overrideConfig = tmp.overrideConfig;
4478
4479        handleLaunchActivity(r, currentIntent, "handleRelaunchActivity");
4480
4481        if (!tmp.onlyLocalRequest) {
4482            try {
4483                ActivityManagerNative.getDefault().activityRelaunched(r.token);
4484                if (r.window != null) {
4485                    r.window.reportActivityRelaunched();
4486                }
4487            } catch (RemoteException e) {
4488                throw e.rethrowFromSystemServer();
4489            }
4490        }
4491    }
4492
4493    private void callCallActivityOnSaveInstanceState(ActivityClientRecord r) {
4494        r.state = new Bundle();
4495        r.state.setAllowFds(false);
4496        if (r.isPersistable()) {
4497            r.persistentState = new PersistableBundle();
4498            mInstrumentation.callActivityOnSaveInstanceState(r.activity, r.state,
4499                    r.persistentState);
4500        } else {
4501            mInstrumentation.callActivityOnSaveInstanceState(r.activity, r.state);
4502        }
4503    }
4504
4505    ArrayList<ComponentCallbacks2> collectComponentCallbacks(
4506            boolean allActivities, Configuration newConfig) {
4507        ArrayList<ComponentCallbacks2> callbacks
4508                = new ArrayList<ComponentCallbacks2>();
4509
4510        synchronized (mResourcesManager) {
4511            final int NAPP = mAllApplications.size();
4512            for (int i=0; i<NAPP; i++) {
4513                callbacks.add(mAllApplications.get(i));
4514            }
4515            final int NACT = mActivities.size();
4516            for (int i=0; i<NACT; i++) {
4517                ActivityClientRecord ar = mActivities.valueAt(i);
4518                Activity a = ar.activity;
4519                if (a != null) {
4520                    Configuration thisConfig = applyConfigCompatMainThread(
4521                            mCurDefaultDisplayDpi, newConfig,
4522                            ar.packageInfo.getCompatibilityInfo());
4523                    if (!ar.activity.mFinished && (allActivities || !ar.paused)) {
4524                        // If the activity is currently resumed, its configuration
4525                        // needs to change right now.
4526                        callbacks.add(a);
4527                    } else if (thisConfig != null) {
4528                        // Otherwise, we will tell it about the change
4529                        // the next time it is resumed or shown.  Note that
4530                        // the activity manager may, before then, decide the
4531                        // activity needs to be destroyed to handle its new
4532                        // configuration.
4533                        if (DEBUG_CONFIGURATION) {
4534                            Slog.v(TAG, "Setting activity "
4535                                    + ar.activityInfo.name + " newConfig=" + thisConfig);
4536                        }
4537                        ar.newConfig = thisConfig;
4538                    }
4539                }
4540            }
4541            final int NSVC = mServices.size();
4542            for (int i=0; i<NSVC; i++) {
4543                callbacks.add(mServices.valueAt(i));
4544            }
4545        }
4546        synchronized (mProviderMap) {
4547            final int NPRV = mLocalProviders.size();
4548            for (int i=0; i<NPRV; i++) {
4549                callbacks.add(mLocalProviders.valueAt(i).mLocalProvider);
4550            }
4551        }
4552
4553        return callbacks;
4554    }
4555
4556    /**
4557     * Updates the configuration for an Activity. The ActivityClientRecord's
4558     * {@link ActivityClientRecord#overrideConfig} is used to compute the final Configuration for
4559     * that Activity. {@link ActivityClientRecord#tmpConfig} is used as a temporary for delivering
4560     * the updated Configuration.
4561     * @param r ActivityClientRecord representing the Activity.
4562     * @param newBaseConfig The new configuration to use. This may be augmented with
4563     *                      {@link ActivityClientRecord#overrideConfig}.
4564     * @param reportToActivity true if the change should be reported to the Activity's callback.
4565     */
4566    private void performConfigurationChangedForActivity(ActivityClientRecord r,
4567                                                        Configuration newBaseConfig,
4568                                                        boolean reportToActivity) {
4569        r.tmpConfig.setTo(newBaseConfig);
4570        if (r.overrideConfig != null) {
4571            r.tmpConfig.updateFrom(r.overrideConfig);
4572        }
4573        performConfigurationChanged(r.activity, r.token, r.tmpConfig, r.overrideConfig,
4574                reportToActivity);
4575        freeTextLayoutCachesIfNeeded(r.activity.mCurrentConfig.diff(r.tmpConfig));
4576    }
4577
4578    /**
4579     * Decides whether to update an Activity's configuration and whether to tell the
4580     * Activity/Component about it.
4581     * @param cb The component callback to notify of configuration change.
4582     * @param activityToken The Activity binder token for which this configuration change happened.
4583     *                      If the change is global, this is null.
4584     * @param newConfig The new configuration.
4585     * @param overrideConfig The override config that differentiates the Activity's configuration
4586     *                       from the base global configuration.
4587     * @param reportToActivity Notify the Activity of the change.
4588     */
4589    private void performConfigurationChanged(ComponentCallbacks2 cb,
4590                                             IBinder activityToken,
4591                                             Configuration newConfig,
4592                                             Configuration overrideConfig,
4593                                             boolean reportToActivity) {
4594        // Only for Activity objects, check that they actually call up to their
4595        // superclass implementation.  ComponentCallbacks2 is an interface, so
4596        // we check the runtime type and act accordingly.
4597        Activity activity = (cb instanceof Activity) ? (Activity) cb : null;
4598        if (activity != null) {
4599            activity.mCalled = false;
4600        }
4601
4602        boolean shouldChangeConfig = false;
4603        if ((activity == null) || (activity.mCurrentConfig == null)) {
4604            shouldChangeConfig = true;
4605        } else {
4606
4607            // If the new config is the same as the config this Activity
4608            // is already running with then don't bother calling
4609            // onConfigurationChanged
4610            int diff = activity.mCurrentConfig.diff(newConfig);
4611            if (diff != 0) {
4612                // If this activity doesn't handle any of the config changes then don't bother
4613                // calling onConfigurationChanged as we're going to destroy it.
4614                // Except in the case where the configuration changed on the activity manager side,
4615                // but wasn't big enough to cause a resource change so the activity wasn't destroyed.
4616                // In this case we still want to change the configuration of the activity but not
4617                // report it to the app.
4618                if ((~activity.mActivityInfo.getRealConfigChanged() & diff) == 0
4619                        || !reportToActivity) {
4620                    shouldChangeConfig = true;
4621                }
4622            }
4623        }
4624
4625        if (DEBUG_CONFIGURATION) {
4626            Slog.v(TAG, "Config callback " + cb + ": shouldChangeConfig=" + shouldChangeConfig);
4627        }
4628
4629        if (shouldChangeConfig) {
4630            if (activityToken != null) {
4631                // We only update an Activity's configuration if this is not a global
4632                // configuration change. This must also be done before the callback,
4633                // or else we violate the contract that the new resources are available
4634                // in {@link ComponentCallbacks2#onConfigurationChanged(Configuration)}.
4635                mResourcesManager.updateResourcesForActivity(activityToken, overrideConfig);
4636            }
4637
4638            if (reportToActivity) {
4639                Configuration configToReport = newConfig;
4640
4641                if (cb instanceof ContextThemeWrapper) {
4642                    // ContextThemeWrappers may override the configuration for that context.
4643                    // We must check and apply any overrides defined.
4644                    ContextThemeWrapper contextThemeWrapper = (ContextThemeWrapper) cb;
4645                    final Configuration localOverrideConfig =
4646                            contextThemeWrapper.getOverrideConfiguration();
4647                    if (localOverrideConfig != null) {
4648                        configToReport = new Configuration(newConfig);
4649                        configToReport.updateFrom(localOverrideConfig);
4650                    }
4651                }
4652
4653                cb.onConfigurationChanged(configToReport);
4654            }
4655
4656            if (activity != null) {
4657                if (reportToActivity && !activity.mCalled) {
4658                    throw new SuperNotCalledException(
4659                            "Activity " + activity.getLocalClassName() +
4660                            " did not call through to super.onConfigurationChanged()");
4661                }
4662                activity.mConfigChangeFlags = 0;
4663                activity.mCurrentConfig = new Configuration(newConfig);
4664            }
4665        }
4666    }
4667
4668    public final void applyConfigurationToResources(Configuration config) {
4669        synchronized (mResourcesManager) {
4670            mResourcesManager.applyConfigurationToResourcesLocked(config, null);
4671        }
4672    }
4673
4674    final Configuration applyCompatConfiguration(int displayDensity) {
4675        Configuration config = mConfiguration;
4676        if (mCompatConfiguration == null) {
4677            mCompatConfiguration = new Configuration();
4678        }
4679        mCompatConfiguration.setTo(mConfiguration);
4680        if (mResourcesManager.applyCompatConfigurationLocked(displayDensity,
4681                mCompatConfiguration)) {
4682            config = mCompatConfiguration;
4683        }
4684        return config;
4685    }
4686
4687    final void handleConfigurationChanged(Configuration config, CompatibilityInfo compat) {
4688
4689        int configDiff = 0;
4690
4691        synchronized (mResourcesManager) {
4692            if (mPendingConfiguration != null) {
4693                if (!mPendingConfiguration.isOtherSeqNewer(config)) {
4694                    config = mPendingConfiguration;
4695                    mCurDefaultDisplayDpi = config.densityDpi;
4696                    updateDefaultDensity();
4697                }
4698                mPendingConfiguration = null;
4699            }
4700
4701            if (config == null) {
4702                return;
4703            }
4704
4705            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handle configuration changed: "
4706                    + config);
4707
4708            mResourcesManager.applyConfigurationToResourcesLocked(config, compat);
4709
4710            if (mConfiguration == null) {
4711                mConfiguration = new Configuration();
4712            }
4713            if (!mConfiguration.isOtherSeqNewer(config) && compat == null) {
4714                return;
4715            }
4716
4717            configDiff = mConfiguration.updateFrom(config);
4718            config = applyCompatConfiguration(mCurDefaultDisplayDpi);
4719
4720            final Theme systemTheme = getSystemContext().getTheme();
4721            if ((systemTheme.getChangingConfigurations() & configDiff) != 0) {
4722                systemTheme.rebase();
4723            }
4724        }
4725
4726        ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(false, config);
4727
4728        freeTextLayoutCachesIfNeeded(configDiff);
4729
4730        if (callbacks != null) {
4731            final int N = callbacks.size();
4732            for (int i=0; i<N; i++) {
4733                ComponentCallbacks2 cb = callbacks.get(i);
4734                if (cb instanceof Activity) {
4735                    // If callback is an Activity - call corresponding method to consider override
4736                    // config and avoid onConfigurationChanged if it hasn't changed.
4737                    Activity a = (Activity) cb;
4738                    performConfigurationChangedForActivity(mActivities.get(a.getActivityToken()),
4739                            config, REPORT_TO_ACTIVITY);
4740                } else {
4741                    performConfigurationChanged(cb, null, config, null, REPORT_TO_ACTIVITY);
4742                }
4743            }
4744        }
4745    }
4746
4747    static void freeTextLayoutCachesIfNeeded(int configDiff) {
4748        if (configDiff != 0) {
4749            // Ask text layout engine to free its caches if there is a locale change
4750            boolean hasLocaleConfigChange = ((configDiff & ActivityInfo.CONFIG_LOCALE) != 0);
4751            if (hasLocaleConfigChange) {
4752                Canvas.freeTextLayoutCaches();
4753                if (DEBUG_CONFIGURATION) Slog.v(TAG, "Cleared TextLayout Caches");
4754            }
4755        }
4756    }
4757
4758    final void handleActivityConfigurationChanged(ActivityConfigChangeData data,
4759            boolean reportToActivity) {
4760        ActivityClientRecord r = mActivities.get(data.activityToken);
4761        if (r == null || r.activity == null) {
4762            return;
4763        }
4764
4765        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handle activity config changed: "
4766                + r.activityInfo.name + ", with callback=" + reportToActivity);
4767
4768        r.overrideConfig = data.overrideConfig;
4769        performConfigurationChangedForActivity(r, mCompatConfiguration, reportToActivity);
4770        mSomeActivitiesChanged = true;
4771    }
4772
4773    final void handleProfilerControl(boolean start, ProfilerInfo profilerInfo, int profileType) {
4774        if (start) {
4775            try {
4776                switch (profileType) {
4777                    default:
4778                        mProfiler.setProfiler(profilerInfo);
4779                        mProfiler.startProfiling();
4780                        break;
4781                }
4782            } catch (RuntimeException e) {
4783                Slog.w(TAG, "Profiling failed on path " + profilerInfo.profileFile
4784                        + " -- can the process access this path?");
4785            } finally {
4786                try {
4787                    profilerInfo.profileFd.close();
4788                } catch (IOException e) {
4789                    Slog.w(TAG, "Failure closing profile fd", e);
4790                }
4791            }
4792        } else {
4793            switch (profileType) {
4794                default:
4795                    mProfiler.stopProfiling();
4796                    break;
4797            }
4798        }
4799    }
4800
4801    /**
4802     * Public entrypoint to stop profiling. This is required to end profiling when the app crashes,
4803     * so that profiler data won't be lost.
4804     *
4805     * @hide
4806     */
4807    public void stopProfiling() {
4808        mProfiler.stopProfiling();
4809    }
4810
4811    static final void handleDumpHeap(boolean managed, DumpHeapData dhd) {
4812        if (managed) {
4813            try {
4814                Debug.dumpHprofData(dhd.path, dhd.fd.getFileDescriptor());
4815            } catch (IOException e) {
4816                Slog.w(TAG, "Managed heap dump failed on path " + dhd.path
4817                        + " -- can the process access this path?");
4818            } finally {
4819                try {
4820                    dhd.fd.close();
4821                } catch (IOException e) {
4822                    Slog.w(TAG, "Failure closing profile fd", e);
4823                }
4824            }
4825        } else {
4826            Debug.dumpNativeHeap(dhd.fd.getFileDescriptor());
4827        }
4828        try {
4829            ActivityManagerNative.getDefault().dumpHeapFinished(dhd.path);
4830        } catch (RemoteException e) {
4831            throw e.rethrowFromSystemServer();
4832        }
4833    }
4834
4835    final void handleDispatchPackageBroadcast(int cmd, String[] packages) {
4836        boolean hasPkgInfo = false;
4837        switch (cmd) {
4838            case IApplicationThread.PACKAGE_REMOVED:
4839            case IApplicationThread.PACKAGE_REMOVED_DONT_KILL:
4840            {
4841                final boolean killApp = cmd == IApplicationThread.PACKAGE_REMOVED;
4842                if (packages == null) {
4843                    break;
4844                }
4845                synchronized (mResourcesManager) {
4846                    for (int i = packages.length - 1; i >= 0; i--) {
4847                        if (!hasPkgInfo) {
4848                            WeakReference<LoadedApk> ref = mPackages.get(packages[i]);
4849                            if (ref != null && ref.get() != null) {
4850                                hasPkgInfo = true;
4851                            } else {
4852                                ref = mResourcePackages.get(packages[i]);
4853                                if (ref != null && ref.get() != null) {
4854                                    hasPkgInfo = true;
4855                                }
4856                            }
4857                        }
4858                        if (killApp) {
4859                            mPackages.remove(packages[i]);
4860                            mResourcePackages.remove(packages[i]);
4861                        }
4862                    }
4863                }
4864                break;
4865            }
4866            case IApplicationThread.PACKAGE_REPLACED:
4867            {
4868                if (packages == null) {
4869                    break;
4870                }
4871                synchronized (mResourcesManager) {
4872                    for (int i = packages.length - 1; i >= 0; i--) {
4873                        WeakReference<LoadedApk> ref = mPackages.get(packages[i]);
4874                        LoadedApk pkgInfo = ref != null ? ref.get() : null;
4875                        if (pkgInfo != null) {
4876                            hasPkgInfo = true;
4877                        } else {
4878                            ref = mResourcePackages.get(packages[i]);
4879                            pkgInfo = ref != null ? ref.get() : null;
4880                            if (pkgInfo != null) {
4881                                hasPkgInfo = true;
4882                            }
4883                        }
4884                        // If the package is being replaced, yet it still has a valid
4885                        // LoadedApk object, the package was updated with _DONT_KILL.
4886                        // Adjust it's internal references to the application info and
4887                        // resources.
4888                        if (pkgInfo != null) {
4889                            try {
4890                                final String packageName = packages[i];
4891                                final ApplicationInfo aInfo =
4892                                        sPackageManager.getApplicationInfo(
4893                                                packageName,
4894                                                0 /*flags*/,
4895                                                UserHandle.myUserId());
4896
4897                                if (mActivities.size() > 0) {
4898                                    for (ActivityClientRecord ar : mActivities.values()) {
4899                                        if (ar.activityInfo.applicationInfo.packageName
4900                                                .equals(packageName)) {
4901                                            ar.activityInfo.applicationInfo = aInfo;
4902                                            ar.packageInfo = pkgInfo;
4903                                        }
4904                                    }
4905                                }
4906                                final List<String> oldPaths =
4907                                        sPackageManager.getPreviousCodePaths(packageName);
4908                                pkgInfo.updateApplicationInfo(aInfo, oldPaths);
4909                            } catch (RemoteException e) {
4910                            }
4911                        }
4912                    }
4913                }
4914                break;
4915            }
4916        }
4917        ApplicationPackageManager.handlePackageBroadcast(cmd, packages, hasPkgInfo);
4918    }
4919
4920    final void handleLowMemory() {
4921        ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(true, null);
4922
4923        final int N = callbacks.size();
4924        for (int i=0; i<N; i++) {
4925            callbacks.get(i).onLowMemory();
4926        }
4927
4928        // Ask SQLite to free up as much memory as it can, mostly from its page caches.
4929        if (Process.myUid() != Process.SYSTEM_UID) {
4930            int sqliteReleased = SQLiteDatabase.releaseMemory();
4931            EventLog.writeEvent(SQLITE_MEM_RELEASED_EVENT_LOG_TAG, sqliteReleased);
4932        }
4933
4934        // Ask graphics to free up as much as possible (font/image caches)
4935        Canvas.freeCaches();
4936
4937        // Ask text layout engine to free also as much as possible
4938        Canvas.freeTextLayoutCaches();
4939
4940        BinderInternal.forceGc("mem");
4941    }
4942
4943    final void handleTrimMemory(int level) {
4944        if (DEBUG_MEMORY_TRIM) Slog.v(TAG, "Trimming memory to level: " + level);
4945
4946        ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(true, null);
4947
4948        final int N = callbacks.size();
4949        for (int i = 0; i < N; i++) {
4950            callbacks.get(i).onTrimMemory(level);
4951        }
4952
4953        WindowManagerGlobal.getInstance().trimMemory(level);
4954    }
4955
4956    private void setupGraphicsSupport(LoadedApk info, File cacheDir) {
4957        if (Process.isIsolated()) {
4958            // Isolated processes aren't going to do UI.
4959            return;
4960        }
4961        try {
4962            int uid = Process.myUid();
4963            String[] packages = getPackageManager().getPackagesForUid(uid);
4964
4965            if (packages != null) {
4966                ThreadedRenderer.setupDiskCache(cacheDir);
4967                RenderScriptCacheDir.setupDiskCache(cacheDir);
4968            }
4969        } catch (RemoteException e) {
4970            throw e.rethrowFromSystemServer();
4971        }
4972    }
4973
4974    private void updateDefaultDensity() {
4975        final int densityDpi = mCurDefaultDisplayDpi;
4976        if (!mDensityCompatMode
4977                && densityDpi != Configuration.DENSITY_DPI_UNDEFINED
4978                && densityDpi != DisplayMetrics.DENSITY_DEVICE) {
4979            DisplayMetrics.DENSITY_DEVICE = densityDpi;
4980            Bitmap.setDefaultDensity(densityDpi);
4981        }
4982    }
4983
4984    private void handleBindApplication(AppBindData data) {
4985        // Register the UI Thread as a sensitive thread to the runtime.
4986        VMRuntime.registerSensitiveThread();
4987        if (data.trackAllocation) {
4988            DdmVmInternal.enableRecentAllocations(true);
4989        }
4990
4991        // Note when this process has started.
4992        Process.setStartTimes(SystemClock.elapsedRealtime(), SystemClock.uptimeMillis());
4993
4994        mBoundApplication = data;
4995        mConfiguration = new Configuration(data.config);
4996        mCompatConfiguration = new Configuration(data.config);
4997
4998        mProfiler = new Profiler();
4999        if (data.initProfilerInfo != null) {
5000            mProfiler.profileFile = data.initProfilerInfo.profileFile;
5001            mProfiler.profileFd = data.initProfilerInfo.profileFd;
5002            mProfiler.samplingInterval = data.initProfilerInfo.samplingInterval;
5003            mProfiler.autoStopProfiler = data.initProfilerInfo.autoStopProfiler;
5004        }
5005
5006        // send up app name; do this *before* waiting for debugger
5007        Process.setArgV0(data.processName);
5008        android.ddm.DdmHandleAppName.setAppName(data.processName,
5009                                                UserHandle.myUserId());
5010
5011        if (data.persistent) {
5012            // Persistent processes on low-memory devices do not get to
5013            // use hardware accelerated drawing, since this can add too much
5014            // overhead to the process.
5015            if (!ActivityManager.isHighEndGfx()) {
5016                ThreadedRenderer.disable(false);
5017            }
5018        }
5019
5020        if (mProfiler.profileFd != null) {
5021            mProfiler.startProfiling();
5022        }
5023
5024        // If the app is Honeycomb MR1 or earlier, switch its AsyncTask
5025        // implementation to use the pool executor.  Normally, we use the
5026        // serialized executor as the default. This has to happen in the
5027        // main thread so the main looper is set right.
5028        if (data.appInfo.targetSdkVersion <= android.os.Build.VERSION_CODES.HONEYCOMB_MR1) {
5029            AsyncTask.setDefaultExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
5030        }
5031
5032        Message.updateCheckRecycle(data.appInfo.targetSdkVersion);
5033
5034        /*
5035         * Before spawning a new process, reset the time zone to be the system time zone.
5036         * This needs to be done because the system time zone could have changed after the
5037         * the spawning of this process. Without doing this this process would have the incorrect
5038         * system time zone.
5039         */
5040        TimeZone.setDefault(null);
5041
5042        data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
5043
5044        /**
5045         * Switch this process to density compatibility mode if needed.
5046         */
5047        if ((data.appInfo.flags&ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES)
5048                == 0) {
5049            mDensityCompatMode = true;
5050            Bitmap.setDefaultDensity(DisplayMetrics.DENSITY_DEFAULT);
5051        }
5052        updateDefaultDensity();
5053
5054        final boolean is24Hr = "24".equals(mCoreSettings.getString(Settings.System.TIME_12_24));
5055        DateFormat.set24HourTimePref(is24Hr);
5056
5057        View.mDebugViewAttributes =
5058                mCoreSettings.getInt(Settings.Global.DEBUG_VIEW_ATTRIBUTES, 0) != 0;
5059
5060        /**
5061         * For system applications on userdebug/eng builds, log stack
5062         * traces of disk and network access to dropbox for analysis.
5063         */
5064        if ((data.appInfo.flags &
5065             (ApplicationInfo.FLAG_SYSTEM |
5066              ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0) {
5067            StrictMode.conditionallyEnableDebugLogging();
5068        }
5069
5070        /**
5071         * For apps targetting Honeycomb or later, we don't allow network usage
5072         * on the main event loop / UI thread. This is what ultimately throws
5073         * {@link NetworkOnMainThreadException}.
5074         */
5075        if (data.appInfo.targetSdkVersion >= Build.VERSION_CODES.HONEYCOMB) {
5076            StrictMode.enableDeathOnNetwork();
5077        }
5078
5079        /**
5080         * For apps targetting N or later, we don't allow file:// Uri exposure.
5081         * This is what ultimately throws {@link FileUriExposedException}.
5082         */
5083        if (data.appInfo.targetSdkVersion >= Build.VERSION_CODES.N) {
5084            StrictMode.enableDeathOnFileUriExposure();
5085        }
5086
5087        NetworkSecurityPolicy.getInstance().setCleartextTrafficPermitted(
5088                (data.appInfo.flags & ApplicationInfo.FLAG_USES_CLEARTEXT_TRAFFIC) != 0);
5089
5090        if (data.debugMode != IApplicationThread.DEBUG_OFF) {
5091            // XXX should have option to change the port.
5092            Debug.changeDebugPort(8100);
5093            if (data.debugMode == IApplicationThread.DEBUG_WAIT) {
5094                Slog.w(TAG, "Application " + data.info.getPackageName()
5095                      + " is waiting for the debugger on port 8100...");
5096
5097                IActivityManager mgr = ActivityManagerNative.getDefault();
5098                try {
5099                    mgr.showWaitingForDebugger(mAppThread, true);
5100                } catch (RemoteException ex) {
5101                    throw ex.rethrowFromSystemServer();
5102                }
5103
5104                Debug.waitForDebugger();
5105
5106                try {
5107                    mgr.showWaitingForDebugger(mAppThread, false);
5108                } catch (RemoteException ex) {
5109                    throw ex.rethrowFromSystemServer();
5110                }
5111
5112            } else {
5113                Slog.w(TAG, "Application " + data.info.getPackageName()
5114                      + " can be debugged on port 8100...");
5115            }
5116        }
5117
5118        // Allow application-generated systrace messages if we're debuggable.
5119        boolean isAppDebuggable = (data.appInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
5120        Trace.setAppTracingAllowed(isAppDebuggable);
5121        if (isAppDebuggable && data.enableBinderTracking) {
5122            Binder.enableTracing();
5123        }
5124
5125        /**
5126         * Initialize the default http proxy in this process for the reasons we set the time zone.
5127         */
5128        final IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE);
5129        if (b != null) {
5130            // In pre-boot mode (doing initial launch to collect password), not
5131            // all system is up.  This includes the connectivity service, so don't
5132            // crash if we can't get it.
5133            final IConnectivityManager service = IConnectivityManager.Stub.asInterface(b);
5134            try {
5135                final ProxyInfo proxyInfo = service.getProxyForNetwork(null);
5136                Proxy.setHttpProxySystemProperty(proxyInfo);
5137            } catch (RemoteException e) {
5138                throw e.rethrowFromSystemServer();
5139            }
5140        }
5141
5142        // Instrumentation info affects the class loader, so load it before
5143        // setting up the app context.
5144        final InstrumentationInfo ii;
5145        if (data.instrumentationName != null) {
5146            try {
5147                ii = new ApplicationPackageManager(null, getPackageManager())
5148                        .getInstrumentationInfo(data.instrumentationName, 0);
5149            } catch (PackageManager.NameNotFoundException e) {
5150                throw new RuntimeException(
5151                        "Unable to find instrumentation info for: " + data.instrumentationName);
5152            }
5153
5154            mInstrumentationPackageName = ii.packageName;
5155            mInstrumentationAppDir = ii.sourceDir;
5156            mInstrumentationSplitAppDirs = ii.splitSourceDirs;
5157            mInstrumentationLibDir = ii.nativeLibraryDir;
5158            mInstrumentedAppDir = data.info.getAppDir();
5159            mInstrumentedSplitAppDirs = data.info.getSplitAppDirs();
5160            mInstrumentedLibDir = data.info.getLibDir();
5161        } else {
5162            ii = null;
5163        }
5164
5165        final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);
5166        synchronized (mResourcesManager) {
5167            /*
5168             * Initialize the default locales in this process for the reasons we set the time zone.
5169             *
5170             * We do this through ResourcesManager, since we need to do locale negotiation.
5171             */
5172            mResourcesManager.setDefaultLocalesLocked(data.config.getLocales());
5173
5174            /*
5175             * Update the system configuration since its preloaded and might not
5176             * reflect configuration changes. The configuration object passed
5177             * in AppBindData can be safely assumed to be up to date
5178             */
5179            mResourcesManager.applyConfigurationToResourcesLocked(data.config, data.compatInfo);
5180            mCurDefaultDisplayDpi = data.config.densityDpi;
5181
5182            // This calls mResourcesManager so keep it within the synchronized block.
5183            applyCompatConfiguration(mCurDefaultDisplayDpi);
5184        }
5185
5186        if (!Process.isIsolated() && !"android".equals(appContext.getPackageName())) {
5187            // This cache location probably points at credential-encrypted
5188            // storage which may not be accessible yet; assign it anyway instead
5189            // of pointing at device-encrypted storage.
5190            final File cacheDir = appContext.getCacheDir();
5191            if (cacheDir != null) {
5192                // Provide a usable directory for temporary files
5193                System.setProperty("java.io.tmpdir", cacheDir.getAbsolutePath());
5194            } else {
5195                Log.v(TAG, "Unable to initialize \"java.io.tmpdir\" property "
5196                        + "due to missing cache directory");
5197            }
5198
5199            // Setup a location to store generated/compiled graphics code.
5200            final Context deviceContext = appContext.createDeviceProtectedStorageContext();
5201            final File codeCacheDir = deviceContext.getCodeCacheDir();
5202            if (codeCacheDir != null) {
5203                setupGraphicsSupport(data.info, codeCacheDir);
5204            } else {
5205                Log.e(TAG, "Unable to setupGraphicsSupport due to missing code-cache directory");
5206            }
5207
5208            // Add the lib dir path to hardware renderer so that vulkan layers
5209            // can be searched for within that directory.
5210            ThreadedRenderer.setLibDir(data.info.getLibDir());
5211        }
5212
5213        // Install the Network Security Config Provider. This must happen before the application
5214        // code is loaded to prevent issues with instances of TLS objects being created before
5215        // the provider is installed.
5216        NetworkSecurityConfigProvider.install(appContext);
5217
5218        // Continue loading instrumentation.
5219        if (ii != null) {
5220            final ApplicationInfo instrApp = new ApplicationInfo();
5221            ii.copyTo(instrApp);
5222            instrApp.initForUser(UserHandle.myUserId());
5223            final LoadedApk pi = getPackageInfo(instrApp, data.compatInfo,
5224                    appContext.getClassLoader(), false, true, false);
5225            final ContextImpl instrContext = ContextImpl.createAppContext(this, pi);
5226
5227            try {
5228                final ClassLoader cl = instrContext.getClassLoader();
5229                mInstrumentation = (Instrumentation)
5230                    cl.loadClass(data.instrumentationName.getClassName()).newInstance();
5231            } catch (Exception e) {
5232                throw new RuntimeException(
5233                    "Unable to instantiate instrumentation "
5234                    + data.instrumentationName + ": " + e.toString(), e);
5235            }
5236
5237            final ComponentName component = new ComponentName(ii.packageName, ii.name);
5238            mInstrumentation.init(this, instrContext, appContext, component,
5239                    data.instrumentationWatcher, data.instrumentationUiAutomationConnection);
5240
5241            if (mProfiler.profileFile != null && !ii.handleProfiling
5242                    && mProfiler.profileFd == null) {
5243                mProfiler.handlingProfiling = true;
5244                final File file = new File(mProfiler.profileFile);
5245                file.getParentFile().mkdirs();
5246                Debug.startMethodTracing(file.toString(), 8 * 1024 * 1024);
5247            }
5248        } else {
5249            mInstrumentation = new Instrumentation();
5250        }
5251
5252        if ((data.appInfo.flags&ApplicationInfo.FLAG_LARGE_HEAP) != 0) {
5253            dalvik.system.VMRuntime.getRuntime().clearGrowthLimit();
5254        } else {
5255            // Small heap, clamp to the current growth limit and let the heap release
5256            // pages after the growth limit to the non growth limit capacity. b/18387825
5257            dalvik.system.VMRuntime.getRuntime().clampGrowthLimit();
5258        }
5259
5260        // Allow disk access during application and provider setup. This could
5261        // block processing ordered broadcasts, but later processing would
5262        // probably end up doing the same disk access.
5263        final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskWrites();
5264        try {
5265            // If the app is being launched for full backup or restore, bring it up in
5266            // a restricted environment with the base application class.
5267            Application app = data.info.makeApplication(data.restrictedBackupMode, null);
5268            mInitialApplication = app;
5269
5270            // don't bring up providers in restricted mode; they may depend on the
5271            // app's custom Application class
5272            if (!data.restrictedBackupMode) {
5273                if (!ArrayUtils.isEmpty(data.providers)) {
5274                    installContentProviders(app, data.providers);
5275                    // For process that contains content providers, we want to
5276                    // ensure that the JIT is enabled "at some point".
5277                    mH.sendEmptyMessageDelayed(H.ENABLE_JIT, 10*1000);
5278                }
5279            }
5280
5281            // Do this after providers, since instrumentation tests generally start their
5282            // test thread at this point, and we don't want that racing.
5283            try {
5284                mInstrumentation.onCreate(data.instrumentationArgs);
5285            }
5286            catch (Exception e) {
5287                throw new RuntimeException(
5288                    "Exception thrown in onCreate() of "
5289                    + data.instrumentationName + ": " + e.toString(), e);
5290            }
5291
5292            try {
5293                mInstrumentation.callApplicationOnCreate(app);
5294            } catch (Exception e) {
5295                if (!mInstrumentation.onException(app, e)) {
5296                    throw new RuntimeException(
5297                        "Unable to create application " + app.getClass().getName()
5298                        + ": " + e.toString(), e);
5299                }
5300            }
5301        } finally {
5302            StrictMode.setThreadPolicy(savedPolicy);
5303        }
5304    }
5305
5306    /*package*/ final void finishInstrumentation(int resultCode, Bundle results) {
5307        IActivityManager am = ActivityManagerNative.getDefault();
5308        if (mProfiler.profileFile != null && mProfiler.handlingProfiling
5309                && mProfiler.profileFd == null) {
5310            Debug.stopMethodTracing();
5311        }
5312        //Slog.i(TAG, "am: " + ActivityManagerNative.getDefault()
5313        //      + ", app thr: " + mAppThread);
5314        try {
5315            am.finishInstrumentation(mAppThread, resultCode, results);
5316        } catch (RemoteException ex) {
5317            throw ex.rethrowFromSystemServer();
5318        }
5319    }
5320
5321    private void installContentProviders(
5322            Context context, List<ProviderInfo> providers) {
5323        final ArrayList<IActivityManager.ContentProviderHolder> results =
5324            new ArrayList<IActivityManager.ContentProviderHolder>();
5325
5326        for (ProviderInfo cpi : providers) {
5327            if (DEBUG_PROVIDER) {
5328                StringBuilder buf = new StringBuilder(128);
5329                buf.append("Pub ");
5330                buf.append(cpi.authority);
5331                buf.append(": ");
5332                buf.append(cpi.name);
5333                Log.i(TAG, buf.toString());
5334            }
5335            IActivityManager.ContentProviderHolder cph = installProvider(context, null, cpi,
5336                    false /*noisy*/, true /*noReleaseNeeded*/, true /*stable*/);
5337            if (cph != null) {
5338                cph.noReleaseNeeded = true;
5339                results.add(cph);
5340            }
5341        }
5342
5343        try {
5344            ActivityManagerNative.getDefault().publishContentProviders(
5345                getApplicationThread(), results);
5346        } catch (RemoteException ex) {
5347            throw ex.rethrowFromSystemServer();
5348        }
5349    }
5350
5351    public final IContentProvider acquireProvider(
5352            Context c, String auth, int userId, boolean stable) {
5353        final IContentProvider provider = acquireExistingProvider(c, auth, userId, stable);
5354        if (provider != null) {
5355            return provider;
5356        }
5357
5358        // There is a possible race here.  Another thread may try to acquire
5359        // the same provider at the same time.  When this happens, we want to ensure
5360        // that the first one wins.
5361        // Note that we cannot hold the lock while acquiring and installing the
5362        // provider since it might take a long time to run and it could also potentially
5363        // be re-entrant in the case where the provider is in the same process.
5364        IActivityManager.ContentProviderHolder holder = null;
5365        try {
5366            holder = ActivityManagerNative.getDefault().getContentProvider(
5367                    getApplicationThread(), auth, userId, stable);
5368        } catch (RemoteException ex) {
5369            throw ex.rethrowFromSystemServer();
5370        }
5371        if (holder == null) {
5372            Slog.e(TAG, "Failed to find provider info for " + auth);
5373            return null;
5374        }
5375
5376        // Install provider will increment the reference count for us, and break
5377        // any ties in the race.
5378        holder = installProvider(c, holder, holder.info,
5379                true /*noisy*/, holder.noReleaseNeeded, stable);
5380        return holder.provider;
5381    }
5382
5383    private final void incProviderRefLocked(ProviderRefCount prc, boolean stable) {
5384        if (stable) {
5385            prc.stableCount += 1;
5386            if (prc.stableCount == 1) {
5387                // We are acquiring a new stable reference on the provider.
5388                int unstableDelta;
5389                if (prc.removePending) {
5390                    // We have a pending remove operation, which is holding the
5391                    // last unstable reference.  At this point we are converting
5392                    // that unstable reference to our new stable reference.
5393                    unstableDelta = -1;
5394                    // Cancel the removal of the provider.
5395                    if (DEBUG_PROVIDER) {
5396                        Slog.v(TAG, "incProviderRef: stable "
5397                                + "snatched provider from the jaws of death");
5398                    }
5399                    prc.removePending = false;
5400                    // There is a race! It fails to remove the message, which
5401                    // will be handled in completeRemoveProvider().
5402                    mH.removeMessages(H.REMOVE_PROVIDER, prc);
5403                } else {
5404                    unstableDelta = 0;
5405                }
5406                try {
5407                    if (DEBUG_PROVIDER) {
5408                        Slog.v(TAG, "incProviderRef Now stable - "
5409                                + prc.holder.info.name + ": unstableDelta="
5410                                + unstableDelta);
5411                    }
5412                    ActivityManagerNative.getDefault().refContentProvider(
5413                            prc.holder.connection, 1, unstableDelta);
5414                } catch (RemoteException e) {
5415                    //do nothing content provider object is dead any way
5416                }
5417            }
5418        } else {
5419            prc.unstableCount += 1;
5420            if (prc.unstableCount == 1) {
5421                // We are acquiring a new unstable reference on the provider.
5422                if (prc.removePending) {
5423                    // Oh look, we actually have a remove pending for the
5424                    // provider, which is still holding the last unstable
5425                    // reference.  We just need to cancel that to take new
5426                    // ownership of the reference.
5427                    if (DEBUG_PROVIDER) {
5428                        Slog.v(TAG, "incProviderRef: unstable "
5429                                + "snatched provider from the jaws of death");
5430                    }
5431                    prc.removePending = false;
5432                    mH.removeMessages(H.REMOVE_PROVIDER, prc);
5433                } else {
5434                    // First unstable ref, increment our count in the
5435                    // activity manager.
5436                    try {
5437                        if (DEBUG_PROVIDER) {
5438                            Slog.v(TAG, "incProviderRef: Now unstable - "
5439                                    + prc.holder.info.name);
5440                        }
5441                        ActivityManagerNative.getDefault().refContentProvider(
5442                                prc.holder.connection, 0, 1);
5443                    } catch (RemoteException e) {
5444                        //do nothing content provider object is dead any way
5445                    }
5446                }
5447            }
5448        }
5449    }
5450
5451    public final IContentProvider acquireExistingProvider(
5452            Context c, String auth, int userId, boolean stable) {
5453        synchronized (mProviderMap) {
5454            final ProviderKey key = new ProviderKey(auth, userId);
5455            final ProviderClientRecord pr = mProviderMap.get(key);
5456            if (pr == null) {
5457                return null;
5458            }
5459
5460            IContentProvider provider = pr.mProvider;
5461            IBinder jBinder = provider.asBinder();
5462            if (!jBinder.isBinderAlive()) {
5463                // The hosting process of the provider has died; we can't
5464                // use this one.
5465                Log.i(TAG, "Acquiring provider " + auth + " for user " + userId
5466                        + ": existing object's process dead");
5467                handleUnstableProviderDiedLocked(jBinder, true);
5468                return null;
5469            }
5470
5471            // Only increment the ref count if we have one.  If we don't then the
5472            // provider is not reference counted and never needs to be released.
5473            ProviderRefCount prc = mProviderRefCountMap.get(jBinder);
5474            if (prc != null) {
5475                incProviderRefLocked(prc, stable);
5476            }
5477            return provider;
5478        }
5479    }
5480
5481    public final boolean releaseProvider(IContentProvider provider, boolean stable) {
5482        if (provider == null) {
5483            return false;
5484        }
5485
5486        IBinder jBinder = provider.asBinder();
5487        synchronized (mProviderMap) {
5488            ProviderRefCount prc = mProviderRefCountMap.get(jBinder);
5489            if (prc == null) {
5490                // The provider has no ref count, no release is needed.
5491                return false;
5492            }
5493
5494            boolean lastRef = false;
5495            if (stable) {
5496                if (prc.stableCount == 0) {
5497                    if (DEBUG_PROVIDER) Slog.v(TAG,
5498                            "releaseProvider: stable ref count already 0, how?");
5499                    return false;
5500                }
5501                prc.stableCount -= 1;
5502                if (prc.stableCount == 0) {
5503                    // What we do at this point depends on whether there are
5504                    // any unstable refs left: if there are, we just tell the
5505                    // activity manager to decrement its stable count; if there
5506                    // aren't, we need to enqueue this provider to be removed,
5507                    // and convert to holding a single unstable ref while
5508                    // doing so.
5509                    lastRef = prc.unstableCount == 0;
5510                    try {
5511                        if (DEBUG_PROVIDER) {
5512                            Slog.v(TAG, "releaseProvider: No longer stable w/lastRef="
5513                                    + lastRef + " - " + prc.holder.info.name);
5514                        }
5515                        ActivityManagerNative.getDefault().refContentProvider(
5516                                prc.holder.connection, -1, lastRef ? 1 : 0);
5517                    } catch (RemoteException e) {
5518                        //do nothing content provider object is dead any way
5519                    }
5520                }
5521            } else {
5522                if (prc.unstableCount == 0) {
5523                    if (DEBUG_PROVIDER) Slog.v(TAG,
5524                            "releaseProvider: unstable ref count already 0, how?");
5525                    return false;
5526                }
5527                prc.unstableCount -= 1;
5528                if (prc.unstableCount == 0) {
5529                    // If this is the last reference, we need to enqueue
5530                    // this provider to be removed instead of telling the
5531                    // activity manager to remove it at this point.
5532                    lastRef = prc.stableCount == 0;
5533                    if (!lastRef) {
5534                        try {
5535                            if (DEBUG_PROVIDER) {
5536                                Slog.v(TAG, "releaseProvider: No longer unstable - "
5537                                        + prc.holder.info.name);
5538                            }
5539                            ActivityManagerNative.getDefault().refContentProvider(
5540                                    prc.holder.connection, 0, -1);
5541                        } catch (RemoteException e) {
5542                            //do nothing content provider object is dead any way
5543                        }
5544                    }
5545                }
5546            }
5547
5548            if (lastRef) {
5549                if (!prc.removePending) {
5550                    // Schedule the actual remove asynchronously, since we don't know the context
5551                    // this will be called in.
5552                    // TODO: it would be nice to post a delayed message, so
5553                    // if we come back and need the same provider quickly
5554                    // we will still have it available.
5555                    if (DEBUG_PROVIDER) {
5556                        Slog.v(TAG, "releaseProvider: Enqueueing pending removal - "
5557                                + prc.holder.info.name);
5558                    }
5559                    prc.removePending = true;
5560                    Message msg = mH.obtainMessage(H.REMOVE_PROVIDER, prc);
5561                    mH.sendMessage(msg);
5562                } else {
5563                    Slog.w(TAG, "Duplicate remove pending of provider " + prc.holder.info.name);
5564                }
5565            }
5566            return true;
5567        }
5568    }
5569
5570    final void completeRemoveProvider(ProviderRefCount prc) {
5571        synchronized (mProviderMap) {
5572            if (!prc.removePending) {
5573                // There was a race!  Some other client managed to acquire
5574                // the provider before the removal was completed.
5575                // Abort the removal.  We will do it later.
5576                if (DEBUG_PROVIDER) Slog.v(TAG, "completeRemoveProvider: lost the race, "
5577                        + "provider still in use");
5578                return;
5579            }
5580
5581            // More complicated race!! Some client managed to acquire the
5582            // provider and release it before the removal was completed.
5583            // Continue the removal, and abort the next remove message.
5584            prc.removePending = false;
5585
5586            final IBinder jBinder = prc.holder.provider.asBinder();
5587            ProviderRefCount existingPrc = mProviderRefCountMap.get(jBinder);
5588            if (existingPrc == prc) {
5589                mProviderRefCountMap.remove(jBinder);
5590            }
5591
5592            for (int i=mProviderMap.size()-1; i>=0; i--) {
5593                ProviderClientRecord pr = mProviderMap.valueAt(i);
5594                IBinder myBinder = pr.mProvider.asBinder();
5595                if (myBinder == jBinder) {
5596                    mProviderMap.removeAt(i);
5597                }
5598            }
5599        }
5600
5601        try {
5602            if (DEBUG_PROVIDER) {
5603                Slog.v(TAG, "removeProvider: Invoking ActivityManagerNative."
5604                        + "removeContentProvider(" + prc.holder.info.name + ")");
5605            }
5606            ActivityManagerNative.getDefault().removeContentProvider(
5607                    prc.holder.connection, false);
5608        } catch (RemoteException e) {
5609            //do nothing content provider object is dead any way
5610        }
5611    }
5612
5613    final void handleUnstableProviderDied(IBinder provider, boolean fromClient) {
5614        synchronized (mProviderMap) {
5615            handleUnstableProviderDiedLocked(provider, fromClient);
5616        }
5617    }
5618
5619    final void handleUnstableProviderDiedLocked(IBinder provider, boolean fromClient) {
5620        ProviderRefCount prc = mProviderRefCountMap.get(provider);
5621        if (prc != null) {
5622            if (DEBUG_PROVIDER) Slog.v(TAG, "Cleaning up dead provider "
5623                    + provider + " " + prc.holder.info.name);
5624            mProviderRefCountMap.remove(provider);
5625            for (int i=mProviderMap.size()-1; i>=0; i--) {
5626                ProviderClientRecord pr = mProviderMap.valueAt(i);
5627                if (pr != null && pr.mProvider.asBinder() == provider) {
5628                    Slog.i(TAG, "Removing dead content provider:" + pr.mProvider.toString());
5629                    mProviderMap.removeAt(i);
5630                }
5631            }
5632
5633            if (fromClient) {
5634                // We found out about this due to execution in our client
5635                // code.  Tell the activity manager about it now, to ensure
5636                // that the next time we go to do anything with the provider
5637                // it knows it is dead (so we don't race with its death
5638                // notification).
5639                try {
5640                    ActivityManagerNative.getDefault().unstableProviderDied(
5641                            prc.holder.connection);
5642                } catch (RemoteException e) {
5643                    //do nothing content provider object is dead any way
5644                }
5645            }
5646        }
5647    }
5648
5649    final void appNotRespondingViaProvider(IBinder provider) {
5650        synchronized (mProviderMap) {
5651            ProviderRefCount prc = mProviderRefCountMap.get(provider);
5652            if (prc != null) {
5653                try {
5654                    ActivityManagerNative.getDefault()
5655                            .appNotRespondingViaProvider(prc.holder.connection);
5656                } catch (RemoteException e) {
5657                    throw e.rethrowFromSystemServer();
5658                }
5659            }
5660        }
5661    }
5662
5663    private ProviderClientRecord installProviderAuthoritiesLocked(IContentProvider provider,
5664            ContentProvider localProvider, IActivityManager.ContentProviderHolder holder) {
5665        final String auths[] = holder.info.authority.split(";");
5666        final int userId = UserHandle.getUserId(holder.info.applicationInfo.uid);
5667
5668        final ProviderClientRecord pcr = new ProviderClientRecord(
5669                auths, provider, localProvider, holder);
5670        for (String auth : auths) {
5671            final ProviderKey key = new ProviderKey(auth, userId);
5672            final ProviderClientRecord existing = mProviderMap.get(key);
5673            if (existing != null) {
5674                Slog.w(TAG, "Content provider " + pcr.mHolder.info.name
5675                        + " already published as " + auth);
5676            } else {
5677                mProviderMap.put(key, pcr);
5678            }
5679        }
5680        return pcr;
5681    }
5682
5683    /**
5684     * Installs the provider.
5685     *
5686     * Providers that are local to the process or that come from the system server
5687     * may be installed permanently which is indicated by setting noReleaseNeeded to true.
5688     * Other remote providers are reference counted.  The initial reference count
5689     * for all reference counted providers is one.  Providers that are not reference
5690     * counted do not have a reference count (at all).
5691     *
5692     * This method detects when a provider has already been installed.  When this happens,
5693     * it increments the reference count of the existing provider (if appropriate)
5694     * and returns the existing provider.  This can happen due to concurrent
5695     * attempts to acquire the same provider.
5696     */
5697    private IActivityManager.ContentProviderHolder installProvider(Context context,
5698            IActivityManager.ContentProviderHolder holder, ProviderInfo info,
5699            boolean noisy, boolean noReleaseNeeded, boolean stable) {
5700        ContentProvider localProvider = null;
5701        IContentProvider provider;
5702        if (holder == null || holder.provider == null) {
5703            if (DEBUG_PROVIDER || noisy) {
5704                Slog.d(TAG, "Loading provider " + info.authority + ": "
5705                        + info.name);
5706            }
5707            Context c = null;
5708            ApplicationInfo ai = info.applicationInfo;
5709            if (context.getPackageName().equals(ai.packageName)) {
5710                c = context;
5711            } else if (mInitialApplication != null &&
5712                    mInitialApplication.getPackageName().equals(ai.packageName)) {
5713                c = mInitialApplication;
5714            } else {
5715                try {
5716                    c = context.createPackageContext(ai.packageName,
5717                            Context.CONTEXT_INCLUDE_CODE);
5718                } catch (PackageManager.NameNotFoundException e) {
5719                    // Ignore
5720                }
5721            }
5722            if (c == null) {
5723                Slog.w(TAG, "Unable to get context for package " +
5724                      ai.packageName +
5725                      " while loading content provider " +
5726                      info.name);
5727                return null;
5728            }
5729            try {
5730                final java.lang.ClassLoader cl = c.getClassLoader();
5731                localProvider = (ContentProvider)cl.
5732                    loadClass(info.name).newInstance();
5733                provider = localProvider.getIContentProvider();
5734                if (provider == null) {
5735                    Slog.e(TAG, "Failed to instantiate class " +
5736                          info.name + " from sourceDir " +
5737                          info.applicationInfo.sourceDir);
5738                    return null;
5739                }
5740                if (DEBUG_PROVIDER) Slog.v(
5741                    TAG, "Instantiating local provider " + info.name);
5742                // XXX Need to create the correct context for this provider.
5743                localProvider.attachInfo(c, info);
5744            } catch (java.lang.Exception e) {
5745                if (!mInstrumentation.onException(null, e)) {
5746                    throw new RuntimeException(
5747                            "Unable to get provider " + info.name
5748                            + ": " + e.toString(), e);
5749                }
5750                return null;
5751            }
5752        } else {
5753            provider = holder.provider;
5754            if (DEBUG_PROVIDER) Slog.v(TAG, "Installing external provider " + info.authority + ": "
5755                    + info.name);
5756        }
5757
5758        IActivityManager.ContentProviderHolder retHolder;
5759
5760        synchronized (mProviderMap) {
5761            if (DEBUG_PROVIDER) Slog.v(TAG, "Checking to add " + provider
5762                    + " / " + info.name);
5763            IBinder jBinder = provider.asBinder();
5764            if (localProvider != null) {
5765                ComponentName cname = new ComponentName(info.packageName, info.name);
5766                ProviderClientRecord pr = mLocalProvidersByName.get(cname);
5767                if (pr != null) {
5768                    if (DEBUG_PROVIDER) {
5769                        Slog.v(TAG, "installProvider: lost the race, "
5770                                + "using existing local provider");
5771                    }
5772                    provider = pr.mProvider;
5773                } else {
5774                    holder = new IActivityManager.ContentProviderHolder(info);
5775                    holder.provider = provider;
5776                    holder.noReleaseNeeded = true;
5777                    pr = installProviderAuthoritiesLocked(provider, localProvider, holder);
5778                    mLocalProviders.put(jBinder, pr);
5779                    mLocalProvidersByName.put(cname, pr);
5780                }
5781                retHolder = pr.mHolder;
5782            } else {
5783                ProviderRefCount prc = mProviderRefCountMap.get(jBinder);
5784                if (prc != null) {
5785                    if (DEBUG_PROVIDER) {
5786                        Slog.v(TAG, "installProvider: lost the race, updating ref count");
5787                    }
5788                    // We need to transfer our new reference to the existing
5789                    // ref count, releasing the old one...  but only if
5790                    // release is needed (that is, it is not running in the
5791                    // system process).
5792                    if (!noReleaseNeeded) {
5793                        incProviderRefLocked(prc, stable);
5794                        try {
5795                            ActivityManagerNative.getDefault().removeContentProvider(
5796                                    holder.connection, stable);
5797                        } catch (RemoteException e) {
5798                            //do nothing content provider object is dead any way
5799                        }
5800                    }
5801                } else {
5802                    ProviderClientRecord client = installProviderAuthoritiesLocked(
5803                            provider, localProvider, holder);
5804                    if (noReleaseNeeded) {
5805                        prc = new ProviderRefCount(holder, client, 1000, 1000);
5806                    } else {
5807                        prc = stable
5808                                ? new ProviderRefCount(holder, client, 1, 0)
5809                                : new ProviderRefCount(holder, client, 0, 1);
5810                    }
5811                    mProviderRefCountMap.put(jBinder, prc);
5812                }
5813                retHolder = prc.holder;
5814            }
5815        }
5816
5817        return retHolder;
5818    }
5819
5820    private void attach(boolean system) {
5821        sCurrentActivityThread = this;
5822        mSystemThread = system;
5823        if (!system) {
5824            ViewRootImpl.addFirstDrawHandler(new Runnable() {
5825                @Override
5826                public void run() {
5827                    ensureJitEnabled();
5828                }
5829            });
5830            android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",
5831                                                    UserHandle.myUserId());
5832            RuntimeInit.setApplicationObject(mAppThread.asBinder());
5833            final IActivityManager mgr = ActivityManagerNative.getDefault();
5834            try {
5835                mgr.attachApplication(mAppThread);
5836            } catch (RemoteException ex) {
5837                throw ex.rethrowFromSystemServer();
5838            }
5839            // Watch for getting close to heap limit.
5840            BinderInternal.addGcWatcher(new Runnable() {
5841                @Override public void run() {
5842                    if (!mSomeActivitiesChanged) {
5843                        return;
5844                    }
5845                    Runtime runtime = Runtime.getRuntime();
5846                    long dalvikMax = runtime.maxMemory();
5847                    long dalvikUsed = runtime.totalMemory() - runtime.freeMemory();
5848                    if (dalvikUsed > ((3*dalvikMax)/4)) {
5849                        if (DEBUG_MEMORY_TRIM) Slog.d(TAG, "Dalvik max=" + (dalvikMax/1024)
5850                                + " total=" + (runtime.totalMemory()/1024)
5851                                + " used=" + (dalvikUsed/1024));
5852                        mSomeActivitiesChanged = false;
5853                        try {
5854                            mgr.releaseSomeActivities(mAppThread);
5855                        } catch (RemoteException e) {
5856                            throw e.rethrowFromSystemServer();
5857                        }
5858                    }
5859                }
5860            });
5861        } else {
5862            // Don't set application object here -- if the system crashes,
5863            // we can't display an alert, we just want to die die die.
5864            android.ddm.DdmHandleAppName.setAppName("system_process",
5865                    UserHandle.myUserId());
5866            try {
5867                mInstrumentation = new Instrumentation();
5868                ContextImpl context = ContextImpl.createAppContext(
5869                        this, getSystemContext().mPackageInfo);
5870                mInitialApplication = context.mPackageInfo.makeApplication(true, null);
5871                mInitialApplication.onCreate();
5872            } catch (Exception e) {
5873                throw new RuntimeException(
5874                        "Unable to instantiate Application():" + e.toString(), e);
5875            }
5876        }
5877
5878        // add dropbox logging to libcore
5879        DropBox.setReporter(new DropBoxReporter());
5880
5881        ViewRootImpl.addConfigCallback(new ComponentCallbacks2() {
5882            @Override
5883            public void onConfigurationChanged(Configuration newConfig) {
5884                synchronized (mResourcesManager) {
5885                    // We need to apply this change to the resources
5886                    // immediately, because upon returning the view
5887                    // hierarchy will be informed about it.
5888                    if (mResourcesManager.applyConfigurationToResourcesLocked(newConfig, null)) {
5889                        // This actually changed the resources!  Tell
5890                        // everyone about it.
5891                        if (mPendingConfiguration == null ||
5892                                mPendingConfiguration.isOtherSeqNewer(newConfig)) {
5893                            mPendingConfiguration = newConfig;
5894
5895                            sendMessage(H.CONFIGURATION_CHANGED, newConfig);
5896                        }
5897                    }
5898                }
5899            }
5900            @Override
5901            public void onLowMemory() {
5902            }
5903            @Override
5904            public void onTrimMemory(int level) {
5905            }
5906        });
5907    }
5908
5909    public static ActivityThread systemMain() {
5910        // The system process on low-memory devices do not get to use hardware
5911        // accelerated drawing, since this can add too much overhead to the
5912        // process.
5913        if (!ActivityManager.isHighEndGfx()) {
5914            ThreadedRenderer.disable(true);
5915        } else {
5916            ThreadedRenderer.enableForegroundTrimming();
5917        }
5918        ActivityThread thread = new ActivityThread();
5919        thread.attach(true);
5920        return thread;
5921    }
5922
5923    public final void installSystemProviders(List<ProviderInfo> providers) {
5924        if (providers != null) {
5925            installContentProviders(mInitialApplication, providers);
5926        }
5927    }
5928
5929    public int getIntCoreSetting(String key, int defaultValue) {
5930        synchronized (mResourcesManager) {
5931            if (mCoreSettings != null) {
5932                return mCoreSettings.getInt(key, defaultValue);
5933            }
5934            return defaultValue;
5935        }
5936    }
5937
5938    private static class EventLoggingReporter implements EventLogger.Reporter {
5939        @Override
5940        public void report (int code, Object... list) {
5941            EventLog.writeEvent(code, list);
5942        }
5943    }
5944
5945    private class DropBoxReporter implements DropBox.Reporter {
5946
5947        private DropBoxManager dropBox;
5948
5949        public DropBoxReporter() {}
5950
5951        @Override
5952        public void addData(String tag, byte[] data, int flags) {
5953            ensureInitialized();
5954            dropBox.addData(tag, data, flags);
5955        }
5956
5957        @Override
5958        public void addText(String tag, String data) {
5959            ensureInitialized();
5960            dropBox.addText(tag, data);
5961        }
5962
5963        private synchronized void ensureInitialized() {
5964            if (dropBox == null) {
5965                dropBox = (DropBoxManager) getSystemContext().getSystemService(Context.DROPBOX_SERVICE);
5966            }
5967        }
5968    }
5969
5970    public static void main(String[] args) {
5971        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");
5972        SamplingProfilerIntegration.start();
5973
5974        // CloseGuard defaults to true and can be quite spammy.  We
5975        // disable it here, but selectively enable it later (via
5976        // StrictMode) on debug builds, but using DropBox, not logs.
5977        CloseGuard.setEnabled(false);
5978
5979        Environment.initForCurrentUser();
5980
5981        // Set the reporter for event logging in libcore
5982        EventLogger.setReporter(new EventLoggingReporter());
5983
5984        AndroidKeyStoreProvider.install();
5985
5986        // Make sure TrustedCertificateStore looks in the right place for CA certificates
5987        final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
5988        TrustedCertificateStore.setDefaultUserDirectory(configDir);
5989
5990        Process.setArgV0("<pre-initialized>");
5991
5992        Looper.prepareMainLooper();
5993
5994        ActivityThread thread = new ActivityThread();
5995        thread.attach(false);
5996
5997        if (sMainThreadHandler == null) {
5998            sMainThreadHandler = thread.getHandler();
5999        }
6000
6001        if (false) {
6002            Looper.myLooper().setMessageLogging(new
6003                    LogPrinter(Log.DEBUG, "ActivityThread"));
6004        }
6005
6006        // End of event ActivityThreadMain.
6007        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6008        Looper.loop();
6009
6010        throw new RuntimeException("Main thread loop unexpectedly exited");
6011    }
6012}
6013