ActivityThread.java revision 8f5770dcdb6d4cac8294938902ab83528a7feea7
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 (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "
2549                        + r.activityInfo.name + " with config " + config);
2550                Window window = null;
2551                if (r.mPendingRemoveWindow != null && r.mPreserveWindow) {
2552                    window = r.mPendingRemoveWindow;
2553                    r.mPendingRemoveWindow = null;
2554                    r.mPendingRemoveWindowManager = null;
2555                }
2556                activity.attach(appContext, this, getInstrumentation(), r.token,
2557                        r.ident, app, r.intent, r.activityInfo, title, r.parent,
2558                        r.embeddedID, r.lastNonConfigurationInstances, config,
2559                        r.referrer, r.voiceInteractor, window);
2560
2561                if (customIntent != null) {
2562                    activity.mIntent = customIntent;
2563                }
2564                r.lastNonConfigurationInstances = null;
2565                activity.mStartedActivity = false;
2566                int theme = r.activityInfo.getThemeResource();
2567                if (theme != 0) {
2568                    activity.setTheme(theme);
2569                }
2570
2571                activity.mCalled = false;
2572                if (r.isPersistable()) {
2573                    mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
2574                } else {
2575                    mInstrumentation.callActivityOnCreate(activity, r.state);
2576                }
2577                if (!activity.mCalled) {
2578                    throw new SuperNotCalledException(
2579                        "Activity " + r.intent.getComponent().toShortString() +
2580                        " did not call through to super.onCreate()");
2581                }
2582                r.activity = activity;
2583                r.stopped = true;
2584                if (!r.activity.mFinished) {
2585                    activity.performStart();
2586                    r.stopped = false;
2587                }
2588                if (!r.activity.mFinished) {
2589                    if (r.isPersistable()) {
2590                        if (r.state != null || r.persistentState != null) {
2591                            mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state,
2592                                    r.persistentState);
2593                        }
2594                    } else if (r.state != null) {
2595                        mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
2596                    }
2597                }
2598                if (!r.activity.mFinished) {
2599                    activity.mCalled = false;
2600                    if (r.isPersistable()) {
2601                        mInstrumentation.callActivityOnPostCreate(activity, r.state,
2602                                r.persistentState);
2603                    } else {
2604                        mInstrumentation.callActivityOnPostCreate(activity, r.state);
2605                    }
2606                    if (!activity.mCalled) {
2607                        throw new SuperNotCalledException(
2608                            "Activity " + r.intent.getComponent().toShortString() +
2609                            " did not call through to super.onPostCreate()");
2610                    }
2611                }
2612            }
2613            r.paused = true;
2614
2615            mActivities.put(r.token, r);
2616
2617        } catch (SuperNotCalledException e) {
2618            throw e;
2619
2620        } catch (Exception e) {
2621            if (!mInstrumentation.onException(activity, e)) {
2622                throw new RuntimeException(
2623                    "Unable to start activity " + component
2624                    + ": " + e.toString(), e);
2625            }
2626        }
2627
2628        return activity;
2629    }
2630
2631    private Context createBaseContextForActivity(ActivityClientRecord r, final Activity activity) {
2632        int displayId = Display.DEFAULT_DISPLAY;
2633        try {
2634            displayId = ActivityManagerNative.getDefault().getActivityDisplayId(r.token);
2635        } catch (RemoteException e) {
2636            throw e.rethrowFromSystemServer();
2637        }
2638
2639        ContextImpl appContext = ContextImpl.createActivityContext(
2640                this, r.packageInfo, r.token, displayId, r.overrideConfig);
2641        appContext.setOuterContext(activity);
2642        Context baseContext = appContext;
2643
2644        final DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance();
2645        // For debugging purposes, if the activity's package name contains the value of
2646        // the "debug.use-second-display" system property as a substring, then show
2647        // its content on a secondary display if there is one.
2648        String pkgName = SystemProperties.get("debug.second-display.pkg");
2649        if (pkgName != null && !pkgName.isEmpty()
2650                && r.packageInfo.mPackageName.contains(pkgName)) {
2651            for (int id : dm.getDisplayIds()) {
2652                if (id != Display.DEFAULT_DISPLAY) {
2653                    Display display =
2654                            dm.getCompatibleDisplay(id, appContext.getDisplayAdjustments(id));
2655                    baseContext = appContext.createDisplayContext(display);
2656                    break;
2657                }
2658            }
2659        }
2660        return baseContext;
2661    }
2662
2663    private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
2664        // If we are getting ready to gc after going to the background, well
2665        // we are back active so skip it.
2666        unscheduleGcIdler();
2667        mSomeActivitiesChanged = true;
2668
2669        if (r.profilerInfo != null) {
2670            mProfiler.setProfiler(r.profilerInfo);
2671            mProfiler.startProfiling();
2672        }
2673
2674        // Make sure we are running with the most recent config.
2675        handleConfigurationChanged(null, null);
2676
2677        if (localLOGV) Slog.v(
2678            TAG, "Handling launch of " + r);
2679
2680        // Initialize before creating the activity
2681        WindowManagerGlobal.initialize();
2682
2683        Activity a = performLaunchActivity(r, customIntent);
2684
2685        if (a != null) {
2686            r.createdConfig = new Configuration(mConfiguration);
2687            reportSizeConfigurations(r);
2688            Bundle oldState = r.state;
2689            handleResumeActivity(r.token, false, r.isForward,
2690                    !r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);
2691
2692            if (!r.activity.mFinished && r.startsNotResumed) {
2693                // The activity manager actually wants this one to start out
2694                // paused, because it needs to be visible but isn't in the
2695                // foreground.  We accomplish this by going through the
2696                // normal startup (because activities expect to go through
2697                // onResume() the first time they run, before their window
2698                // is displayed), and then pausing it.  However, in this case
2699                // we do -not- need to do the full pause cycle (of freezing
2700                // and such) because the activity manager assumes it can just
2701                // retain the current state it has.
2702                try {
2703                    r.activity.mCalled = false;
2704                    mInstrumentation.callActivityOnPause(r.activity);
2705                    EventLog.writeEvent(LOG_AM_ON_PAUSE_CALLED, UserHandle.myUserId(),
2706                            r.activity.getComponentName().getClassName(), reason);
2707                    // We need to keep around the original state, in case
2708                    // we need to be created again.  But we only do this
2709                    // for pre-Honeycomb apps, which always save their state
2710                    // when pausing, so we can not have them save their state
2711                    // when restarting from a paused state.  For HC and later,
2712                    // we want to (and can) let the state be saved as the normal
2713                    // part of stopping the activity.
2714                    if (r.isPreHoneycomb()) {
2715                        r.state = oldState;
2716                    }
2717                    if (!r.activity.mCalled) {
2718                        throw new SuperNotCalledException(
2719                            "Activity " + r.intent.getComponent().toShortString() +
2720                            " did not call through to super.onPause()");
2721                    }
2722
2723                } catch (SuperNotCalledException e) {
2724                    throw e;
2725
2726                } catch (Exception e) {
2727                    if (!mInstrumentation.onException(r.activity, e)) {
2728                        throw new RuntimeException(
2729                                "Unable to pause activity "
2730                                + r.intent.getComponent().toShortString()
2731                                + ": " + e.toString(), e);
2732                    }
2733                }
2734                r.paused = true;
2735            }
2736        } else {
2737            // If there was an error, for any reason, tell the activity
2738            // manager to stop us.
2739            try {
2740                ActivityManagerNative.getDefault()
2741                    .finishActivity(r.token, Activity.RESULT_CANCELED, null,
2742                            Activity.DONT_FINISH_TASK_WITH_ACTIVITY);
2743            } catch (RemoteException ex) {
2744                throw ex.rethrowFromSystemServer();
2745            }
2746        }
2747    }
2748
2749    private void reportSizeConfigurations(ActivityClientRecord r) {
2750        Configuration[] configurations = r.activity.getResources().getSizeConfigurations();
2751        if (configurations == null) {
2752            return;
2753        }
2754        SparseIntArray horizontal = new SparseIntArray();
2755        SparseIntArray vertical = new SparseIntArray();
2756        SparseIntArray smallest = new SparseIntArray();
2757        for (int i = configurations.length - 1; i >= 0; i--) {
2758            Configuration config = configurations[i];
2759            if (config.screenHeightDp != Configuration.SCREEN_HEIGHT_DP_UNDEFINED) {
2760                vertical.put(config.screenHeightDp, 0);
2761            }
2762            if (config.screenWidthDp != Configuration.SCREEN_WIDTH_DP_UNDEFINED) {
2763                horizontal.put(config.screenWidthDp, 0);
2764            }
2765            if (config.smallestScreenWidthDp != Configuration.SMALLEST_SCREEN_WIDTH_DP_UNDEFINED) {
2766                smallest.put(config.smallestScreenWidthDp, 0);
2767            }
2768        }
2769        try {
2770            ActivityManagerNative.getDefault().reportSizeConfigurations(r.token,
2771                    horizontal.copyKeys(), vertical.copyKeys(), smallest.copyKeys());
2772        } catch (RemoteException ex) {
2773            throw ex.rethrowFromSystemServer();
2774        }
2775
2776    }
2777
2778    private void deliverNewIntents(ActivityClientRecord r, List<ReferrerIntent> intents) {
2779        final int N = intents.size();
2780        for (int i=0; i<N; i++) {
2781            ReferrerIntent intent = intents.get(i);
2782            intent.setExtrasClassLoader(r.activity.getClassLoader());
2783            intent.prepareToEnterProcess();
2784            r.activity.mFragments.noteStateNotSaved();
2785            mInstrumentation.callActivityOnNewIntent(r.activity, intent);
2786        }
2787    }
2788
2789    public final void performNewIntents(IBinder token, List<ReferrerIntent> intents) {
2790        ActivityClientRecord r = mActivities.get(token);
2791        if (r != null) {
2792            final boolean resumed = !r.paused;
2793            if (resumed) {
2794                r.activity.mTemporaryPause = true;
2795                mInstrumentation.callActivityOnPause(r.activity);
2796            }
2797            deliverNewIntents(r, intents);
2798            if (resumed) {
2799                r.activity.performResume();
2800                r.activity.mTemporaryPause = false;
2801            }
2802        }
2803    }
2804
2805    private void handleNewIntent(NewIntentData data) {
2806        performNewIntents(data.token, data.intents);
2807    }
2808
2809    public void handleRequestAssistContextExtras(RequestAssistContextExtras cmd) {
2810        if (mLastAssistStructure != null) {
2811            AssistStructure structure = mLastAssistStructure.get();
2812            if (structure != null) {
2813                structure.clearSendChannel();
2814            }
2815        }
2816        Bundle data = new Bundle();
2817        AssistStructure structure = null;
2818        AssistContent content = new AssistContent();
2819        ActivityClientRecord r = mActivities.get(cmd.activityToken);
2820        Uri referrer = null;
2821        if (r != null) {
2822            r.activity.getApplication().dispatchOnProvideAssistData(r.activity, data);
2823            r.activity.onProvideAssistData(data);
2824            referrer = r.activity.onProvideReferrer();
2825            if (cmd.requestType == ActivityManager.ASSIST_CONTEXT_FULL) {
2826                structure = new AssistStructure(r.activity);
2827                Intent activityIntent = r.activity.getIntent();
2828                if (activityIntent != null && (r.window == null ||
2829                        (r.window.getAttributes().flags
2830                                & WindowManager.LayoutParams.FLAG_SECURE) == 0)) {
2831                    Intent intent = new Intent(activityIntent);
2832                    intent.setFlags(intent.getFlags() & ~(Intent.FLAG_GRANT_WRITE_URI_PERMISSION
2833                            | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION));
2834                    intent.removeUnsafeExtras();
2835                    content.setDefaultIntent(intent);
2836                } else {
2837                    content.setDefaultIntent(new Intent());
2838                }
2839                r.activity.onProvideAssistContent(content);
2840            }
2841        }
2842        if (structure == null) {
2843            structure = new AssistStructure();
2844        }
2845        mLastAssistStructure = new WeakReference<>(structure);
2846        IActivityManager mgr = ActivityManagerNative.getDefault();
2847        try {
2848            mgr.reportAssistContextExtras(cmd.requestToken, data, structure, content, referrer);
2849        } catch (RemoteException e) {
2850            throw e.rethrowFromSystemServer();
2851        }
2852    }
2853
2854    public void handleTranslucentConversionComplete(IBinder token, boolean drawComplete) {
2855        ActivityClientRecord r = mActivities.get(token);
2856        if (r != null) {
2857            r.activity.onTranslucentConversionComplete(drawComplete);
2858        }
2859    }
2860
2861    public void onNewActivityOptions(IBinder token, ActivityOptions options) {
2862        ActivityClientRecord r = mActivities.get(token);
2863        if (r != null) {
2864            r.activity.onNewActivityOptions(options);
2865        }
2866    }
2867
2868    public void handleCancelVisibleBehind(IBinder token) {
2869        ActivityClientRecord r = mActivities.get(token);
2870        if (r != null) {
2871            mSomeActivitiesChanged = true;
2872            final Activity activity = r.activity;
2873            if (activity.mVisibleBehind) {
2874                activity.mCalled = false;
2875                activity.onVisibleBehindCanceled();
2876                // Tick, tick, tick. The activity has 500 msec to return or it will be destroyed.
2877                if (!activity.mCalled) {
2878                    throw new SuperNotCalledException("Activity " + activity.getLocalClassName() +
2879                            " did not call through to super.onVisibleBehindCanceled()");
2880                }
2881                activity.mVisibleBehind = false;
2882            }
2883        }
2884        try {
2885            ActivityManagerNative.getDefault().backgroundResourcesReleased(token);
2886        } catch (RemoteException e) {
2887            throw e.rethrowFromSystemServer();
2888        }
2889    }
2890
2891    public void handleOnBackgroundVisibleBehindChanged(IBinder token, boolean visible) {
2892        ActivityClientRecord r = mActivities.get(token);
2893        if (r != null) {
2894            r.activity.onBackgroundVisibleBehindChanged(visible);
2895        }
2896    }
2897
2898    public void handleInstallProvider(ProviderInfo info) {
2899        final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
2900        try {
2901            installContentProviders(mInitialApplication, Lists.newArrayList(info));
2902        } finally {
2903            StrictMode.setThreadPolicy(oldPolicy);
2904        }
2905    }
2906
2907    private void handleEnterAnimationComplete(IBinder token) {
2908        ActivityClientRecord r = mActivities.get(token);
2909        if (r != null) {
2910            r.activity.dispatchEnterAnimationComplete();
2911        }
2912    }
2913
2914    private void handleStartBinderTracking() {
2915        Binder.enableTracing();
2916    }
2917
2918    private void handleStopBinderTrackingAndDump(ParcelFileDescriptor fd) {
2919        try {
2920            Binder.disableTracing();
2921            Binder.getTransactionTracker().writeTracesToFile(fd);
2922        } finally {
2923            IoUtils.closeQuietly(fd);
2924            Binder.getTransactionTracker().clearTraces();
2925        }
2926    }
2927
2928    private void handleMultiWindowModeChanged(IBinder token, boolean isInMultiWindowMode) {
2929        final ActivityClientRecord r = mActivities.get(token);
2930        if (r != null) {
2931            r.activity.onMultiWindowModeChanged(isInMultiWindowMode);
2932        }
2933    }
2934
2935    private void handlePictureInPictureModeChanged(IBinder token, boolean isInPipMode) {
2936        final ActivityClientRecord r = mActivities.get(token);
2937        if (r != null) {
2938            r.activity.onPictureInPictureModeChanged(isInPipMode);
2939        }
2940    }
2941
2942    private void handleLocalVoiceInteractionStarted(IBinder token, IVoiceInteractor interactor) {
2943        final ActivityClientRecord r = mActivities.get(token);
2944        if (r != null) {
2945            r.voiceInteractor = interactor;
2946            r.activity.setVoiceInteractor(interactor);
2947            if (interactor == null) {
2948                r.activity.onLocalVoiceInteractionStopped();
2949            } else {
2950                r.activity.onLocalVoiceInteractionStarted();
2951            }
2952        }
2953    }
2954
2955    private static final ThreadLocal<Intent> sCurrentBroadcastIntent = new ThreadLocal<Intent>();
2956
2957    /**
2958     * Return the Intent that's currently being handled by a
2959     * BroadcastReceiver on this thread, or null if none.
2960     * @hide
2961     */
2962    public static Intent getIntentBeingBroadcast() {
2963        return sCurrentBroadcastIntent.get();
2964    }
2965
2966    private void handleReceiver(ReceiverData data) {
2967        // If we are getting ready to gc after going to the background, well
2968        // we are back active so skip it.
2969        unscheduleGcIdler();
2970
2971        String component = data.intent.getComponent().getClassName();
2972
2973        LoadedApk packageInfo = getPackageInfoNoCheck(
2974                data.info.applicationInfo, data.compatInfo);
2975
2976        IActivityManager mgr = ActivityManagerNative.getDefault();
2977
2978        BroadcastReceiver receiver;
2979        try {
2980            java.lang.ClassLoader cl = packageInfo.getClassLoader();
2981            data.intent.setExtrasClassLoader(cl);
2982            data.intent.prepareToEnterProcess();
2983            data.setExtrasClassLoader(cl);
2984            receiver = (BroadcastReceiver)cl.loadClass(component).newInstance();
2985        } catch (Exception e) {
2986            if (DEBUG_BROADCAST) Slog.i(TAG,
2987                    "Finishing failed broadcast to " + data.intent.getComponent());
2988            data.sendFinished(mgr);
2989            throw new RuntimeException(
2990                "Unable to instantiate receiver " + component
2991                + ": " + e.toString(), e);
2992        }
2993
2994        try {
2995            Application app = packageInfo.makeApplication(false, mInstrumentation);
2996
2997            if (localLOGV) Slog.v(
2998                TAG, "Performing receive of " + data.intent
2999                + ": app=" + app
3000                + ", appName=" + app.getPackageName()
3001                + ", pkg=" + packageInfo.getPackageName()
3002                + ", comp=" + data.intent.getComponent().toShortString()
3003                + ", dir=" + packageInfo.getAppDir());
3004
3005            ContextImpl context = (ContextImpl)app.getBaseContext();
3006            sCurrentBroadcastIntent.set(data.intent);
3007            receiver.setPendingResult(data);
3008            receiver.onReceive(context.getReceiverRestrictedContext(),
3009                    data.intent);
3010        } catch (Exception e) {
3011            if (DEBUG_BROADCAST) Slog.i(TAG,
3012                    "Finishing failed broadcast to " + data.intent.getComponent());
3013            data.sendFinished(mgr);
3014            if (!mInstrumentation.onException(receiver, e)) {
3015                throw new RuntimeException(
3016                    "Unable to start receiver " + component
3017                    + ": " + e.toString(), e);
3018            }
3019        } finally {
3020            sCurrentBroadcastIntent.set(null);
3021        }
3022
3023        if (receiver.getPendingResult() != null) {
3024            data.finish();
3025        }
3026    }
3027
3028    // Instantiate a BackupAgent and tell it that it's alive
3029    private void handleCreateBackupAgent(CreateBackupAgentData data) {
3030        if (DEBUG_BACKUP) Slog.v(TAG, "handleCreateBackupAgent: " + data);
3031
3032        // Sanity check the requested target package's uid against ours
3033        try {
3034            PackageInfo requestedPackage = getPackageManager().getPackageInfo(
3035                    data.appInfo.packageName, 0, UserHandle.myUserId());
3036            if (requestedPackage.applicationInfo.uid != Process.myUid()) {
3037                Slog.w(TAG, "Asked to instantiate non-matching package "
3038                        + data.appInfo.packageName);
3039                return;
3040            }
3041        } catch (RemoteException e) {
3042            throw e.rethrowFromSystemServer();
3043        }
3044
3045        // no longer idle; we have backup work to do
3046        unscheduleGcIdler();
3047
3048        // instantiate the BackupAgent class named in the manifest
3049        LoadedApk packageInfo = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
3050        String packageName = packageInfo.mPackageName;
3051        if (packageName == null) {
3052            Slog.d(TAG, "Asked to create backup agent for nonexistent package");
3053            return;
3054        }
3055
3056        String classname = data.appInfo.backupAgentName;
3057        // full backup operation but no app-supplied agent?  use the default implementation
3058        if (classname == null && (data.backupMode == IApplicationThread.BACKUP_MODE_FULL
3059                || data.backupMode == IApplicationThread.BACKUP_MODE_RESTORE_FULL)) {
3060            classname = "android.app.backup.FullBackupAgent";
3061        }
3062
3063        try {
3064            IBinder binder = null;
3065            BackupAgent agent = mBackupAgents.get(packageName);
3066            if (agent != null) {
3067                // reusing the existing instance
3068                if (DEBUG_BACKUP) {
3069                    Slog.v(TAG, "Reusing existing agent instance");
3070                }
3071                binder = agent.onBind();
3072            } else {
3073                try {
3074                    if (DEBUG_BACKUP) Slog.v(TAG, "Initializing agent class " + classname);
3075
3076                    java.lang.ClassLoader cl = packageInfo.getClassLoader();
3077                    agent = (BackupAgent) cl.loadClass(classname).newInstance();
3078
3079                    // set up the agent's context
3080                    ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
3081                    context.setOuterContext(agent);
3082                    agent.attach(context);
3083
3084                    agent.onCreate();
3085                    binder = agent.onBind();
3086                    mBackupAgents.put(packageName, agent);
3087                } catch (Exception e) {
3088                    // If this is during restore, fail silently; otherwise go
3089                    // ahead and let the user see the crash.
3090                    Slog.e(TAG, "Agent threw during creation: " + e);
3091                    if (data.backupMode != IApplicationThread.BACKUP_MODE_RESTORE
3092                            && data.backupMode != IApplicationThread.BACKUP_MODE_RESTORE_FULL) {
3093                        throw e;
3094                    }
3095                    // falling through with 'binder' still null
3096                }
3097            }
3098
3099            // tell the OS that we're live now
3100            try {
3101                ActivityManagerNative.getDefault().backupAgentCreated(packageName, binder);
3102            } catch (RemoteException e) {
3103                throw e.rethrowFromSystemServer();
3104            }
3105        } catch (Exception e) {
3106            throw new RuntimeException("Unable to create BackupAgent "
3107                    + classname + ": " + e.toString(), e);
3108        }
3109    }
3110
3111    // Tear down a BackupAgent
3112    private void handleDestroyBackupAgent(CreateBackupAgentData data) {
3113        if (DEBUG_BACKUP) Slog.v(TAG, "handleDestroyBackupAgent: " + data);
3114
3115        LoadedApk packageInfo = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
3116        String packageName = packageInfo.mPackageName;
3117        BackupAgent agent = mBackupAgents.get(packageName);
3118        if (agent != null) {
3119            try {
3120                agent.onDestroy();
3121            } catch (Exception e) {
3122                Slog.w(TAG, "Exception thrown in onDestroy by backup agent of " + data.appInfo);
3123                e.printStackTrace();
3124            }
3125            mBackupAgents.remove(packageName);
3126        } else {
3127            Slog.w(TAG, "Attempt to destroy unknown backup agent " + data);
3128        }
3129    }
3130
3131    private void handleCreateService(CreateServiceData data) {
3132        // If we are getting ready to gc after going to the background, well
3133        // we are back active so skip it.
3134        unscheduleGcIdler();
3135
3136        LoadedApk packageInfo = getPackageInfoNoCheck(
3137                data.info.applicationInfo, data.compatInfo);
3138        Service service = null;
3139        try {
3140            java.lang.ClassLoader cl = packageInfo.getClassLoader();
3141            service = (Service) cl.loadClass(data.info.name).newInstance();
3142        } catch (Exception e) {
3143            if (!mInstrumentation.onException(service, e)) {
3144                throw new RuntimeException(
3145                    "Unable to instantiate service " + data.info.name
3146                    + ": " + e.toString(), e);
3147            }
3148        }
3149
3150        try {
3151            if (localLOGV) Slog.v(TAG, "Creating service " + data.info.name);
3152
3153            ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
3154            context.setOuterContext(service);
3155
3156            Application app = packageInfo.makeApplication(false, mInstrumentation);
3157            service.attach(context, this, data.info.name, data.token, app,
3158                    ActivityManagerNative.getDefault());
3159            service.onCreate();
3160            mServices.put(data.token, service);
3161            try {
3162                ActivityManagerNative.getDefault().serviceDoneExecuting(
3163                        data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
3164            } catch (RemoteException e) {
3165                throw e.rethrowFromSystemServer();
3166            }
3167        } catch (Exception e) {
3168            if (!mInstrumentation.onException(service, e)) {
3169                throw new RuntimeException(
3170                    "Unable to create service " + data.info.name
3171                    + ": " + e.toString(), e);
3172            }
3173        }
3174    }
3175
3176    private void handleBindService(BindServiceData data) {
3177        Service s = mServices.get(data.token);
3178        if (DEBUG_SERVICE)
3179            Slog.v(TAG, "handleBindService s=" + s + " rebind=" + data.rebind);
3180        if (s != null) {
3181            try {
3182                data.intent.setExtrasClassLoader(s.getClassLoader());
3183                data.intent.prepareToEnterProcess();
3184                try {
3185                    if (!data.rebind) {
3186                        IBinder binder = s.onBind(data.intent);
3187                        ActivityManagerNative.getDefault().publishService(
3188                                data.token, data.intent, binder);
3189                    } else {
3190                        s.onRebind(data.intent);
3191                        ActivityManagerNative.getDefault().serviceDoneExecuting(
3192                                data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
3193                    }
3194                    ensureJitEnabled();
3195                } catch (RemoteException ex) {
3196                    throw ex.rethrowFromSystemServer();
3197                }
3198            } catch (Exception e) {
3199                if (!mInstrumentation.onException(s, e)) {
3200                    throw new RuntimeException(
3201                            "Unable to bind to service " + s
3202                            + " with " + data.intent + ": " + e.toString(), e);
3203                }
3204            }
3205        }
3206    }
3207
3208    private void handleUnbindService(BindServiceData data) {
3209        Service s = mServices.get(data.token);
3210        if (s != null) {
3211            try {
3212                data.intent.setExtrasClassLoader(s.getClassLoader());
3213                data.intent.prepareToEnterProcess();
3214                boolean doRebind = s.onUnbind(data.intent);
3215                try {
3216                    if (doRebind) {
3217                        ActivityManagerNative.getDefault().unbindFinished(
3218                                data.token, data.intent, doRebind);
3219                    } else {
3220                        ActivityManagerNative.getDefault().serviceDoneExecuting(
3221                                data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
3222                    }
3223                } catch (RemoteException ex) {
3224                    throw ex.rethrowFromSystemServer();
3225                }
3226            } catch (Exception e) {
3227                if (!mInstrumentation.onException(s, e)) {
3228                    throw new RuntimeException(
3229                            "Unable to unbind to service " + s
3230                            + " with " + data.intent + ": " + e.toString(), e);
3231                }
3232            }
3233        }
3234    }
3235
3236    private void handleDumpService(DumpComponentInfo info) {
3237        final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
3238        try {
3239            Service s = mServices.get(info.token);
3240            if (s != null) {
3241                PrintWriter pw = new FastPrintWriter(new FileOutputStream(
3242                        info.fd.getFileDescriptor()));
3243                s.dump(info.fd.getFileDescriptor(), pw, info.args);
3244                pw.flush();
3245            }
3246        } finally {
3247            IoUtils.closeQuietly(info.fd);
3248            StrictMode.setThreadPolicy(oldPolicy);
3249        }
3250    }
3251
3252    private void handleDumpActivity(DumpComponentInfo info) {
3253        final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
3254        try {
3255            ActivityClientRecord r = mActivities.get(info.token);
3256            if (r != null && r.activity != null) {
3257                PrintWriter pw = new FastPrintWriter(new FileOutputStream(
3258                        info.fd.getFileDescriptor()));
3259                r.activity.dump(info.prefix, info.fd.getFileDescriptor(), pw, info.args);
3260                pw.flush();
3261            }
3262        } finally {
3263            IoUtils.closeQuietly(info.fd);
3264            StrictMode.setThreadPolicy(oldPolicy);
3265        }
3266    }
3267
3268    private void handleDumpProvider(DumpComponentInfo info) {
3269        final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
3270        try {
3271            ProviderClientRecord r = mLocalProviders.get(info.token);
3272            if (r != null && r.mLocalProvider != null) {
3273                PrintWriter pw = new FastPrintWriter(new FileOutputStream(
3274                        info.fd.getFileDescriptor()));
3275                r.mLocalProvider.dump(info.fd.getFileDescriptor(), pw, info.args);
3276                pw.flush();
3277            }
3278        } finally {
3279            IoUtils.closeQuietly(info.fd);
3280            StrictMode.setThreadPolicy(oldPolicy);
3281        }
3282    }
3283
3284    private void handleServiceArgs(ServiceArgsData data) {
3285        Service s = mServices.get(data.token);
3286        if (s != null) {
3287            try {
3288                if (data.args != null) {
3289                    data.args.setExtrasClassLoader(s.getClassLoader());
3290                    data.args.prepareToEnterProcess();
3291                }
3292                int res;
3293                if (!data.taskRemoved) {
3294                    res = s.onStartCommand(data.args, data.flags, data.startId);
3295                } else {
3296                    s.onTaskRemoved(data.args);
3297                    res = Service.START_TASK_REMOVED_COMPLETE;
3298                }
3299
3300                QueuedWork.waitToFinish();
3301
3302                try {
3303                    ActivityManagerNative.getDefault().serviceDoneExecuting(
3304                            data.token, SERVICE_DONE_EXECUTING_START, data.startId, res);
3305                } catch (RemoteException e) {
3306                    throw e.rethrowFromSystemServer();
3307                }
3308                ensureJitEnabled();
3309            } catch (Exception e) {
3310                if (!mInstrumentation.onException(s, e)) {
3311                    throw new RuntimeException(
3312                            "Unable to start service " + s
3313                            + " with " + data.args + ": " + e.toString(), e);
3314                }
3315            }
3316        }
3317    }
3318
3319    private void handleStopService(IBinder token) {
3320        Service s = mServices.remove(token);
3321        if (s != null) {
3322            try {
3323                if (localLOGV) Slog.v(TAG, "Destroying service " + s);
3324                s.onDestroy();
3325                Context context = s.getBaseContext();
3326                if (context instanceof ContextImpl) {
3327                    final String who = s.getClassName();
3328                    ((ContextImpl) context).scheduleFinalCleanup(who, "Service");
3329                }
3330
3331                QueuedWork.waitToFinish();
3332
3333                try {
3334                    ActivityManagerNative.getDefault().serviceDoneExecuting(
3335                            token, SERVICE_DONE_EXECUTING_STOP, 0, 0);
3336                } catch (RemoteException e) {
3337                    throw e.rethrowFromSystemServer();
3338                }
3339            } catch (Exception e) {
3340                if (!mInstrumentation.onException(s, e)) {
3341                    throw new RuntimeException(
3342                            "Unable to stop service " + s
3343                            + ": " + e.toString(), e);
3344                }
3345                Slog.i(TAG, "handleStopService: exception for " + token, e);
3346            }
3347        } else {
3348            Slog.i(TAG, "handleStopService: token=" + token + " not found.");
3349        }
3350        //Slog.i(TAG, "Running services: " + mServices);
3351    }
3352
3353    public final ActivityClientRecord performResumeActivity(IBinder token,
3354            boolean clearHide, String reason) {
3355        ActivityClientRecord r = mActivities.get(token);
3356        if (localLOGV) Slog.v(TAG, "Performing resume of " + r
3357                + " finished=" + r.activity.mFinished);
3358        if (r != null && !r.activity.mFinished) {
3359            if (clearHide) {
3360                r.hideForNow = false;
3361                r.activity.mStartedActivity = false;
3362            }
3363            try {
3364                r.activity.onStateNotSaved();
3365                r.activity.mFragments.noteStateNotSaved();
3366                if (r.pendingIntents != null) {
3367                    deliverNewIntents(r, r.pendingIntents);
3368                    r.pendingIntents = null;
3369                }
3370                if (r.pendingResults != null) {
3371                    deliverResults(r, r.pendingResults);
3372                    r.pendingResults = null;
3373                }
3374                r.activity.performResume();
3375
3376                // If there is a pending local relaunch that was requested when the activity was
3377                // paused, it will put the activity into paused state when it finally happens.
3378                // Since the activity resumed before being relaunched, we don't want that to happen,
3379                // so we need to clear the request to relaunch paused.
3380                for (int i = mRelaunchingActivities.size() - 1; i >= 0; i--) {
3381                    final ActivityClientRecord relaunching = mRelaunchingActivities.get(i);
3382                    if (relaunching.token == r.token
3383                            && relaunching.onlyLocalRequest && relaunching.startsNotResumed) {
3384                        relaunching.startsNotResumed = false;
3385                    }
3386                }
3387
3388                EventLog.writeEvent(LOG_AM_ON_RESUME_CALLED, UserHandle.myUserId(),
3389                        r.activity.getComponentName().getClassName(), reason);
3390
3391                r.paused = false;
3392                r.stopped = false;
3393                r.state = null;
3394                r.persistentState = null;
3395            } catch (Exception e) {
3396                if (!mInstrumentation.onException(r.activity, e)) {
3397                    throw new RuntimeException(
3398                        "Unable to resume activity "
3399                        + r.intent.getComponent().toShortString()
3400                        + ": " + e.toString(), e);
3401                }
3402            }
3403        }
3404        return r;
3405    }
3406
3407    static final void cleanUpPendingRemoveWindows(ActivityClientRecord r, boolean force) {
3408        if (r.mPreserveWindow && !force) {
3409            return;
3410        }
3411        if (r.mPendingRemoveWindow != null) {
3412            r.mPendingRemoveWindowManager.removeViewImmediate(
3413                    r.mPendingRemoveWindow.getDecorView());
3414            IBinder wtoken = r.mPendingRemoveWindow.getDecorView().getWindowToken();
3415            if (wtoken != null) {
3416                WindowManagerGlobal.getInstance().closeAll(wtoken,
3417                        r.activity.getClass().getName(), "Activity");
3418            }
3419        }
3420        r.mPendingRemoveWindow = null;
3421        r.mPendingRemoveWindowManager = null;
3422    }
3423
3424    final void handleResumeActivity(IBinder token,
3425            boolean clearHide, boolean isForward, boolean reallyResume, int seq, String reason) {
3426        ActivityClientRecord r = mActivities.get(token);
3427        if (!checkAndUpdateLifecycleSeq(seq, r, "resumeActivity")) {
3428            return;
3429        }
3430
3431        // If we are getting ready to gc after going to the background, well
3432        // we are back active so skip it.
3433        unscheduleGcIdler();
3434        mSomeActivitiesChanged = true;
3435
3436        // TODO Push resumeArgs into the activity for consideration
3437        r = performResumeActivity(token, clearHide, reason);
3438
3439        if (r != null) {
3440            final Activity a = r.activity;
3441
3442            if (localLOGV) Slog.v(
3443                TAG, "Resume " + r + " started activity: " +
3444                a.mStartedActivity + ", hideForNow: " + r.hideForNow
3445                + ", finished: " + a.mFinished);
3446
3447            final int forwardBit = isForward ?
3448                    WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION : 0;
3449
3450            // If the window hasn't yet been added to the window manager,
3451            // and this guy didn't finish itself or start another activity,
3452            // then go ahead and add the window.
3453            boolean willBeVisible = !a.mStartedActivity;
3454            if (!willBeVisible) {
3455                try {
3456                    willBeVisible = ActivityManagerNative.getDefault().willActivityBeVisible(
3457                            a.getActivityToken());
3458                } catch (RemoteException e) {
3459                    throw e.rethrowFromSystemServer();
3460                }
3461            }
3462            if (r.window == null && !a.mFinished && willBeVisible) {
3463                r.window = r.activity.getWindow();
3464                View decor = r.window.getDecorView();
3465                decor.setVisibility(View.INVISIBLE);
3466                ViewManager wm = a.getWindowManager();
3467                WindowManager.LayoutParams l = r.window.getAttributes();
3468                a.mDecor = decor;
3469                l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
3470                l.softInputMode |= forwardBit;
3471                if (r.mPreserveWindow) {
3472                    a.mWindowAdded = true;
3473                    r.mPreserveWindow = false;
3474                }
3475                if (a.mVisibleFromClient && !a.mWindowAdded) {
3476                    a.mWindowAdded = true;
3477                    wm.addView(decor, l);
3478                }
3479
3480            // If the window has already been added, but during resume
3481            // we started another activity, then don't yet make the
3482            // window visible.
3483            } else if (!willBeVisible) {
3484                if (localLOGV) Slog.v(
3485                    TAG, "Launch " + r + " mStartedActivity set");
3486                r.hideForNow = true;
3487            }
3488
3489            // Get rid of anything left hanging around.
3490            cleanUpPendingRemoveWindows(r, false /* force */);
3491
3492            // The window is now visible if it has been added, we are not
3493            // simply finishing, and we are not starting another activity.
3494            if (!r.activity.mFinished && willBeVisible
3495                    && r.activity.mDecor != null && !r.hideForNow) {
3496                if (r.newConfig != null) {
3497                    performConfigurationChangedForActivity(r, r.newConfig, REPORT_TO_ACTIVITY);
3498                    if (DEBUG_CONFIGURATION) Slog.v(TAG, "Resuming activity "
3499                            + r.activityInfo.name + " with newConfig " + r.activity.mCurrentConfig);
3500                    r.newConfig = null;
3501                }
3502                if (localLOGV) Slog.v(TAG, "Resuming " + r + " with isForward="
3503                        + isForward);
3504                WindowManager.LayoutParams l = r.window.getAttributes();
3505                if ((l.softInputMode
3506                        & WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION)
3507                        != forwardBit) {
3508                    l.softInputMode = (l.softInputMode
3509                            & (~WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION))
3510                            | forwardBit;
3511                    if (r.activity.mVisibleFromClient) {
3512                        ViewManager wm = a.getWindowManager();
3513                        View decor = r.window.getDecorView();
3514                        wm.updateViewLayout(decor, l);
3515                    }
3516                }
3517                r.activity.mVisibleFromServer = true;
3518                mNumVisibleActivities++;
3519                if (r.activity.mVisibleFromClient) {
3520                    r.activity.makeVisible();
3521                }
3522            }
3523
3524            if (!r.onlyLocalRequest) {
3525                r.nextIdle = mNewActivities;
3526                mNewActivities = r;
3527                if (localLOGV) Slog.v(
3528                    TAG, "Scheduling idle handler for " + r);
3529                Looper.myQueue().addIdleHandler(new Idler());
3530            }
3531            r.onlyLocalRequest = false;
3532
3533            // Tell the activity manager we have resumed.
3534            if (reallyResume) {
3535                try {
3536                    ActivityManagerNative.getDefault().activityResumed(token);
3537                } catch (RemoteException ex) {
3538                    throw ex.rethrowFromSystemServer();
3539                }
3540            }
3541
3542        } else {
3543            // If an exception was thrown when trying to resume, then
3544            // just end this activity.
3545            try {
3546                ActivityManagerNative.getDefault()
3547                    .finishActivity(token, Activity.RESULT_CANCELED, null,
3548                            Activity.DONT_FINISH_TASK_WITH_ACTIVITY);
3549            } catch (RemoteException ex) {
3550                throw ex.rethrowFromSystemServer();
3551            }
3552        }
3553    }
3554
3555    private int mThumbnailWidth = -1;
3556    private int mThumbnailHeight = -1;
3557    private Bitmap mAvailThumbnailBitmap = null;
3558    private Canvas mThumbnailCanvas = null;
3559
3560    private Bitmap createThumbnailBitmap(ActivityClientRecord r) {
3561        Bitmap thumbnail = mAvailThumbnailBitmap;
3562        try {
3563            if (thumbnail == null) {
3564                int w = mThumbnailWidth;
3565                int h;
3566                if (w < 0) {
3567                    Resources res = r.activity.getResources();
3568                    int wId = com.android.internal.R.dimen.thumbnail_width;
3569                    int hId = com.android.internal.R.dimen.thumbnail_height;
3570                    mThumbnailWidth = w = res.getDimensionPixelSize(wId);
3571                    mThumbnailHeight = h = res.getDimensionPixelSize(hId);
3572                } else {
3573                    h = mThumbnailHeight;
3574                }
3575
3576                // On platforms where we don't want thumbnails, set dims to (0,0)
3577                if ((w > 0) && (h > 0)) {
3578                    thumbnail = Bitmap.createBitmap(r.activity.getResources().getDisplayMetrics(),
3579                            w, h, THUMBNAIL_FORMAT);
3580                    thumbnail.eraseColor(0);
3581                }
3582            }
3583
3584            if (thumbnail != null) {
3585                Canvas cv = mThumbnailCanvas;
3586                if (cv == null) {
3587                    mThumbnailCanvas = cv = new Canvas();
3588                }
3589
3590                cv.setBitmap(thumbnail);
3591                if (!r.activity.onCreateThumbnail(thumbnail, cv)) {
3592                    mAvailThumbnailBitmap = thumbnail;
3593                    thumbnail = null;
3594                }
3595                cv.setBitmap(null);
3596            }
3597
3598        } catch (Exception e) {
3599            if (!mInstrumentation.onException(r.activity, e)) {
3600                throw new RuntimeException(
3601                        "Unable to create thumbnail of "
3602                        + r.intent.getComponent().toShortString()
3603                        + ": " + e.toString(), e);
3604            }
3605            thumbnail = null;
3606        }
3607
3608        return thumbnail;
3609    }
3610
3611    private void handlePauseActivity(IBinder token, boolean finished,
3612            boolean userLeaving, int configChanges, boolean dontReport, int seq) {
3613        ActivityClientRecord r = mActivities.get(token);
3614        if (DEBUG_ORDER) Slog.d(TAG, "handlePauseActivity " + r + ", seq: " + seq);
3615        if (!checkAndUpdateLifecycleSeq(seq, r, "pauseActivity")) {
3616            return;
3617        }
3618        if (r != null) {
3619            //Slog.v(TAG, "userLeaving=" + userLeaving + " handling pause of " + r);
3620            if (userLeaving) {
3621                performUserLeavingActivity(r);
3622            }
3623
3624            r.activity.mConfigChangeFlags |= configChanges;
3625            performPauseActivity(token, finished, r.isPreHoneycomb(), "handlePauseActivity");
3626
3627            // Make sure any pending writes are now committed.
3628            if (r.isPreHoneycomb()) {
3629                QueuedWork.waitToFinish();
3630            }
3631
3632            // Tell the activity manager we have paused.
3633            if (!dontReport) {
3634                try {
3635                    ActivityManagerNative.getDefault().activityPaused(token);
3636                } catch (RemoteException ex) {
3637                    throw ex.rethrowFromSystemServer();
3638                }
3639            }
3640            mSomeActivitiesChanged = true;
3641        }
3642    }
3643
3644    final void performUserLeavingActivity(ActivityClientRecord r) {
3645        mInstrumentation.callActivityOnUserLeaving(r.activity);
3646    }
3647
3648    final Bundle performPauseActivity(IBinder token, boolean finished,
3649            boolean saveState, String reason) {
3650        ActivityClientRecord r = mActivities.get(token);
3651        return r != null ? performPauseActivity(r, finished, saveState, reason) : null;
3652    }
3653
3654    final Bundle performPauseActivity(ActivityClientRecord r, boolean finished,
3655            boolean saveState, String reason) {
3656        if (r.paused) {
3657            if (r.activity.mFinished) {
3658                // If we are finishing, we won't call onResume() in certain cases.
3659                // So here we likewise don't want to call onPause() if the activity
3660                // isn't resumed.
3661                return null;
3662            }
3663            RuntimeException e = new RuntimeException(
3664                    "Performing pause of activity that is not resumed: "
3665                    + r.intent.getComponent().toShortString());
3666            Slog.e(TAG, e.getMessage(), e);
3667        }
3668        if (finished) {
3669            r.activity.mFinished = true;
3670        }
3671        try {
3672            // Next have the activity save its current state and managed dialogs...
3673            if (!r.activity.mFinished && saveState) {
3674                callCallActivityOnSaveInstanceState(r);
3675            }
3676            // Now we are idle.
3677            r.activity.mCalled = false;
3678            mInstrumentation.callActivityOnPause(r.activity);
3679            EventLog.writeEvent(LOG_AM_ON_PAUSE_CALLED, UserHandle.myUserId(),
3680                    r.activity.getComponentName().getClassName(), reason);
3681            if (!r.activity.mCalled) {
3682                throw new SuperNotCalledException(
3683                    "Activity " + r.intent.getComponent().toShortString() +
3684                    " did not call through to super.onPause()");
3685            }
3686
3687        } catch (SuperNotCalledException e) {
3688            throw e;
3689
3690        } catch (Exception e) {
3691            if (!mInstrumentation.onException(r.activity, e)) {
3692                throw new RuntimeException(
3693                        "Unable to pause activity "
3694                        + r.intent.getComponent().toShortString()
3695                        + ": " + e.toString(), e);
3696            }
3697        }
3698        r.paused = true;
3699
3700        // Notify any outstanding on paused listeners
3701        ArrayList<OnActivityPausedListener> listeners;
3702        synchronized (mOnPauseListeners) {
3703            listeners = mOnPauseListeners.remove(r.activity);
3704        }
3705        int size = (listeners != null ? listeners.size() : 0);
3706        for (int i = 0; i < size; i++) {
3707            listeners.get(i).onPaused(r.activity);
3708        }
3709
3710        return !r.activity.mFinished && saveState ? r.state : null;
3711    }
3712
3713    final void performStopActivity(IBinder token, boolean saveState, String reason) {
3714        ActivityClientRecord r = mActivities.get(token);
3715        performStopActivityInner(r, null, false, saveState, reason);
3716    }
3717
3718    private static class StopInfo implements Runnable {
3719        ActivityClientRecord activity;
3720        Bundle state;
3721        PersistableBundle persistentState;
3722        CharSequence description;
3723
3724        @Override public void run() {
3725            // Tell activity manager we have been stopped.
3726            try {
3727                if (DEBUG_MEMORY_TRIM) Slog.v(TAG, "Reporting activity stopped: " + activity);
3728                ActivityManagerNative.getDefault().activityStopped(
3729                    activity.token, state, persistentState, description);
3730            } catch (RemoteException ex) {
3731                if (ex instanceof TransactionTooLargeException
3732                        && activity.packageInfo.getTargetSdkVersion() < Build.VERSION_CODES.N) {
3733                    Log.e(TAG, "App sent too much data in instance state, so it was ignored", ex);
3734                    return;
3735                }
3736                throw ex.rethrowFromSystemServer();
3737            }
3738        }
3739    }
3740
3741    private static final class ProviderRefCount {
3742        public final IActivityManager.ContentProviderHolder holder;
3743        public final ProviderClientRecord client;
3744        public int stableCount;
3745        public int unstableCount;
3746
3747        // When this is set, the stable and unstable ref counts are 0 and
3748        // we have a pending operation scheduled to remove the ref count
3749        // from the activity manager.  On the activity manager we are still
3750        // holding an unstable ref, though it is not reflected in the counts
3751        // here.
3752        public boolean removePending;
3753
3754        ProviderRefCount(IActivityManager.ContentProviderHolder inHolder,
3755                ProviderClientRecord inClient, int sCount, int uCount) {
3756            holder = inHolder;
3757            client = inClient;
3758            stableCount = sCount;
3759            unstableCount = uCount;
3760        }
3761    }
3762
3763    /**
3764     * Core implementation of stopping an activity.  Note this is a little
3765     * tricky because the server's meaning of stop is slightly different
3766     * than our client -- for the server, stop means to save state and give
3767     * it the result when it is done, but the window may still be visible.
3768     * For the client, we want to call onStop()/onStart() to indicate when
3769     * the activity's UI visibillity changes.
3770     */
3771    private void performStopActivityInner(ActivityClientRecord r,
3772            StopInfo info, boolean keepShown, boolean saveState, String reason) {
3773        if (localLOGV) Slog.v(TAG, "Performing stop of " + r);
3774        if (r != null) {
3775            if (!keepShown && r.stopped) {
3776                if (r.activity.mFinished) {
3777                    // If we are finishing, we won't call onResume() in certain
3778                    // cases.  So here we likewise don't want to call onStop()
3779                    // if the activity isn't resumed.
3780                    return;
3781                }
3782                RuntimeException e = new RuntimeException(
3783                        "Performing stop of activity that is already stopped: "
3784                        + r.intent.getComponent().toShortString());
3785                Slog.e(TAG, e.getMessage(), e);
3786                Slog.e(TAG, r.getStateString());
3787            }
3788
3789            if (info != null) {
3790                try {
3791                    // First create a thumbnail for the activity...
3792                    // For now, don't create the thumbnail here; we are
3793                    // doing that by doing a screen snapshot.
3794                    info.description = r.activity.onCreateDescription();
3795                } catch (Exception e) {
3796                    if (!mInstrumentation.onException(r.activity, e)) {
3797                        throw new RuntimeException(
3798                                "Unable to save state of activity "
3799                                + r.intent.getComponent().toShortString()
3800                                + ": " + e.toString(), e);
3801                    }
3802                }
3803            }
3804
3805            // Next have the activity save its current state and managed dialogs...
3806            if (!r.activity.mFinished && saveState) {
3807                if (r.state == null) {
3808                    callCallActivityOnSaveInstanceState(r);
3809                }
3810            }
3811
3812            if (!keepShown) {
3813                try {
3814                    // Now we are idle.
3815                    r.activity.performStop(false /*preserveWindow*/);
3816                } catch (Exception e) {
3817                    if (!mInstrumentation.onException(r.activity, e)) {
3818                        throw new RuntimeException(
3819                                "Unable to stop activity "
3820                                + r.intent.getComponent().toShortString()
3821                                + ": " + e.toString(), e);
3822                    }
3823                }
3824                r.stopped = true;
3825                EventLog.writeEvent(LOG_AM_ON_STOP_CALLED, UserHandle.myUserId(),
3826                        r.activity.getComponentName().getClassName(), reason);
3827            }
3828
3829            r.paused = true;
3830        }
3831    }
3832
3833    private void updateVisibility(ActivityClientRecord r, boolean show) {
3834        View v = r.activity.mDecor;
3835        if (v != null) {
3836            if (show) {
3837                if (!r.activity.mVisibleFromServer) {
3838                    r.activity.mVisibleFromServer = true;
3839                    mNumVisibleActivities++;
3840                    if (r.activity.mVisibleFromClient) {
3841                        r.activity.makeVisible();
3842                    }
3843                }
3844                if (r.newConfig != null) {
3845                    performConfigurationChangedForActivity(r, r.newConfig, REPORT_TO_ACTIVITY);
3846                    if (DEBUG_CONFIGURATION) Slog.v(TAG, "Updating activity vis "
3847                            + r.activityInfo.name + " with new config "
3848                            + r.activity.mCurrentConfig);
3849                    r.newConfig = null;
3850                }
3851            } else {
3852                if (r.activity.mVisibleFromServer) {
3853                    r.activity.mVisibleFromServer = false;
3854                    mNumVisibleActivities--;
3855                    v.setVisibility(View.INVISIBLE);
3856                }
3857            }
3858        }
3859    }
3860
3861    private void handleStopActivity(IBinder token, boolean show, int configChanges, int seq) {
3862        ActivityClientRecord r = mActivities.get(token);
3863        if (!checkAndUpdateLifecycleSeq(seq, r, "stopActivity")) {
3864            return;
3865        }
3866        r.activity.mConfigChangeFlags |= configChanges;
3867
3868        StopInfo info = new StopInfo();
3869        performStopActivityInner(r, info, show, true, "handleStopActivity");
3870
3871        if (localLOGV) Slog.v(
3872            TAG, "Finishing stop of " + r + ": show=" + show
3873            + " win=" + r.window);
3874
3875        updateVisibility(r, show);
3876
3877        // Make sure any pending writes are now committed.
3878        if (!r.isPreHoneycomb()) {
3879            QueuedWork.waitToFinish();
3880        }
3881
3882        // Schedule the call to tell the activity manager we have
3883        // stopped.  We don't do this immediately, because we want to
3884        // have a chance for any other pending work (in particular memory
3885        // trim requests) to complete before you tell the activity
3886        // manager to proceed and allow us to go fully into the background.
3887        info.activity = r;
3888        info.state = r.state;
3889        info.persistentState = r.persistentState;
3890        mH.post(info);
3891        mSomeActivitiesChanged = true;
3892    }
3893
3894    private static boolean checkAndUpdateLifecycleSeq(int seq, ActivityClientRecord r,
3895            String action) {
3896        if (r == null) {
3897            return true;
3898        }
3899        if (seq < r.lastProcessedSeq) {
3900            if (DEBUG_ORDER) Slog.d(TAG, action + " for " + r + " ignored, because seq=" + seq
3901                    + " < mCurrentLifecycleSeq=" + r.lastProcessedSeq);
3902            return false;
3903        }
3904        r.lastProcessedSeq = seq;
3905        return true;
3906    }
3907
3908    final void performRestartActivity(IBinder token) {
3909        ActivityClientRecord r = mActivities.get(token);
3910        if (r.stopped) {
3911            r.activity.performRestart();
3912            r.stopped = false;
3913        }
3914    }
3915
3916    private void handleWindowVisibility(IBinder token, boolean show) {
3917        ActivityClientRecord r = mActivities.get(token);
3918
3919        if (r == null) {
3920            Log.w(TAG, "handleWindowVisibility: no activity for token " + token);
3921            return;
3922        }
3923
3924        if (!show && !r.stopped) {
3925            performStopActivityInner(r, null, show, false, "handleWindowVisibility");
3926        } else if (show && r.stopped) {
3927            // If we are getting ready to gc after going to the background, well
3928            // we are back active so skip it.
3929            unscheduleGcIdler();
3930
3931            r.activity.performRestart();
3932            r.stopped = false;
3933        }
3934        if (r.activity.mDecor != null) {
3935            if (false) Slog.v(
3936                TAG, "Handle window " + r + " visibility: " + show);
3937            updateVisibility(r, show);
3938        }
3939        mSomeActivitiesChanged = true;
3940    }
3941
3942    private void handleSleeping(IBinder token, boolean sleeping) {
3943        ActivityClientRecord r = mActivities.get(token);
3944
3945        if (r == null) {
3946            Log.w(TAG, "handleSleeping: no activity for token " + token);
3947            return;
3948        }
3949
3950        if (sleeping) {
3951            if (!r.stopped && !r.isPreHoneycomb()) {
3952                try {
3953                    // Now we are idle.
3954                    r.activity.performStop(false /*preserveWindow*/);
3955                } catch (Exception e) {
3956                    if (!mInstrumentation.onException(r.activity, e)) {
3957                        throw new RuntimeException(
3958                                "Unable to stop activity "
3959                                + r.intent.getComponent().toShortString()
3960                                + ": " + e.toString(), e);
3961                    }
3962                }
3963                r.stopped = true;
3964                EventLog.writeEvent(LOG_AM_ON_STOP_CALLED, UserHandle.myUserId(),
3965                        r.activity.getComponentName().getClassName(), "sleeping");
3966            }
3967
3968            // Make sure any pending writes are now committed.
3969            if (!r.isPreHoneycomb()) {
3970                QueuedWork.waitToFinish();
3971            }
3972
3973            // Tell activity manager we slept.
3974            try {
3975                ActivityManagerNative.getDefault().activitySlept(r.token);
3976            } catch (RemoteException ex) {
3977                throw ex.rethrowFromSystemServer();
3978            }
3979        } else {
3980            if (r.stopped && r.activity.mVisibleFromServer) {
3981                r.activity.performRestart();
3982                r.stopped = false;
3983            }
3984        }
3985    }
3986
3987    private void handleSetCoreSettings(Bundle coreSettings) {
3988        synchronized (mResourcesManager) {
3989            mCoreSettings = coreSettings;
3990        }
3991        onCoreSettingsChange();
3992    }
3993
3994    private void onCoreSettingsChange() {
3995        boolean debugViewAttributes =
3996                mCoreSettings.getInt(Settings.Global.DEBUG_VIEW_ATTRIBUTES, 0) != 0;
3997        if (debugViewAttributes != View.mDebugViewAttributes) {
3998            View.mDebugViewAttributes = debugViewAttributes;
3999
4000            // request all activities to relaunch for the changes to take place
4001            for (Map.Entry<IBinder, ActivityClientRecord> entry : mActivities.entrySet()) {
4002                requestRelaunchActivity(entry.getKey(), null, null, 0, false, null, null, false,
4003                        false /* preserveWindow */);
4004            }
4005        }
4006    }
4007
4008    private void handleUpdatePackageCompatibilityInfo(UpdateCompatibilityData data) {
4009        LoadedApk apk = peekPackageInfo(data.pkg, false);
4010        if (apk != null) {
4011            apk.setCompatibilityInfo(data.info);
4012        }
4013        apk = peekPackageInfo(data.pkg, true);
4014        if (apk != null) {
4015            apk.setCompatibilityInfo(data.info);
4016        }
4017        handleConfigurationChanged(mConfiguration, data.info);
4018        WindowManagerGlobal.getInstance().reportNewConfiguration(mConfiguration);
4019    }
4020
4021    private void deliverResults(ActivityClientRecord r, List<ResultInfo> results) {
4022        final int N = results.size();
4023        for (int i=0; i<N; i++) {
4024            ResultInfo ri = results.get(i);
4025            try {
4026                if (ri.mData != null) {
4027                    ri.mData.setExtrasClassLoader(r.activity.getClassLoader());
4028                    ri.mData.prepareToEnterProcess();
4029                }
4030                if (DEBUG_RESULTS) Slog.v(TAG,
4031                        "Delivering result to activity " + r + " : " + ri);
4032                r.activity.dispatchActivityResult(ri.mResultWho,
4033                        ri.mRequestCode, ri.mResultCode, ri.mData);
4034            } catch (Exception e) {
4035                if (!mInstrumentation.onException(r.activity, e)) {
4036                    throw new RuntimeException(
4037                            "Failure delivering result " + ri + " to activity "
4038                            + r.intent.getComponent().toShortString()
4039                            + ": " + e.toString(), e);
4040                }
4041            }
4042        }
4043    }
4044
4045    private void handleSendResult(ResultData res) {
4046        ActivityClientRecord r = mActivities.get(res.token);
4047        if (DEBUG_RESULTS) Slog.v(TAG, "Handling send result to " + r);
4048        if (r != null) {
4049            final boolean resumed = !r.paused;
4050            if (!r.activity.mFinished && r.activity.mDecor != null
4051                    && r.hideForNow && resumed) {
4052                // We had hidden the activity because it started another
4053                // one...  we have gotten a result back and we are not
4054                // paused, so make sure our window is visible.
4055                updateVisibility(r, true);
4056            }
4057            if (resumed) {
4058                try {
4059                    // Now we are idle.
4060                    r.activity.mCalled = false;
4061                    r.activity.mTemporaryPause = true;
4062                    mInstrumentation.callActivityOnPause(r.activity);
4063                    if (!r.activity.mCalled) {
4064                        throw new SuperNotCalledException(
4065                            "Activity " + r.intent.getComponent().toShortString()
4066                            + " did not call through to super.onPause()");
4067                    }
4068                } catch (SuperNotCalledException e) {
4069                    throw e;
4070                } catch (Exception e) {
4071                    if (!mInstrumentation.onException(r.activity, e)) {
4072                        throw new RuntimeException(
4073                                "Unable to pause activity "
4074                                + r.intent.getComponent().toShortString()
4075                                + ": " + e.toString(), e);
4076                    }
4077                }
4078            }
4079            deliverResults(r, res.results);
4080            if (resumed) {
4081                r.activity.performResume();
4082                r.activity.mTemporaryPause = false;
4083            }
4084        }
4085    }
4086
4087    public final ActivityClientRecord performDestroyActivity(IBinder token, boolean finishing) {
4088        return performDestroyActivity(token, finishing, 0, false);
4089    }
4090
4091    private ActivityClientRecord performDestroyActivity(IBinder token, boolean finishing,
4092            int configChanges, boolean getNonConfigInstance) {
4093        ActivityClientRecord r = mActivities.get(token);
4094        Class<? extends Activity> activityClass = null;
4095        if (localLOGV) Slog.v(TAG, "Performing finish of " + r);
4096        if (r != null) {
4097            activityClass = r.activity.getClass();
4098            r.activity.mConfigChangeFlags |= configChanges;
4099            if (finishing) {
4100                r.activity.mFinished = true;
4101            }
4102            if (!r.paused) {
4103                try {
4104                    r.activity.mCalled = false;
4105                    mInstrumentation.callActivityOnPause(r.activity);
4106                    EventLog.writeEvent(LOG_AM_ON_PAUSE_CALLED, UserHandle.myUserId(),
4107                            r.activity.getComponentName().getClassName(), "destroy");
4108                    if (!r.activity.mCalled) {
4109                        throw new SuperNotCalledException(
4110                            "Activity " + safeToComponentShortString(r.intent)
4111                            + " did not call through to super.onPause()");
4112                    }
4113                } catch (SuperNotCalledException e) {
4114                    throw e;
4115                } catch (Exception e) {
4116                    if (!mInstrumentation.onException(r.activity, e)) {
4117                        throw new RuntimeException(
4118                                "Unable to pause activity "
4119                                + safeToComponentShortString(r.intent)
4120                                + ": " + e.toString(), e);
4121                    }
4122                }
4123                r.paused = true;
4124            }
4125            if (!r.stopped) {
4126                try {
4127                    r.activity.performStop(r.mPreserveWindow);
4128                } catch (SuperNotCalledException e) {
4129                    throw e;
4130                } catch (Exception e) {
4131                    if (!mInstrumentation.onException(r.activity, e)) {
4132                        throw new RuntimeException(
4133                                "Unable to stop activity "
4134                                + safeToComponentShortString(r.intent)
4135                                + ": " + e.toString(), e);
4136                    }
4137                }
4138                r.stopped = true;
4139                EventLog.writeEvent(LOG_AM_ON_STOP_CALLED, UserHandle.myUserId(),
4140                        r.activity.getComponentName().getClassName(), "destroy");
4141            }
4142            if (getNonConfigInstance) {
4143                try {
4144                    r.lastNonConfigurationInstances
4145                            = r.activity.retainNonConfigurationInstances();
4146                } catch (Exception e) {
4147                    if (!mInstrumentation.onException(r.activity, e)) {
4148                        throw new RuntimeException(
4149                                "Unable to retain activity "
4150                                + r.intent.getComponent().toShortString()
4151                                + ": " + e.toString(), e);
4152                    }
4153                }
4154            }
4155            try {
4156                r.activity.mCalled = false;
4157                mInstrumentation.callActivityOnDestroy(r.activity);
4158                if (!r.activity.mCalled) {
4159                    throw new SuperNotCalledException(
4160                        "Activity " + safeToComponentShortString(r.intent) +
4161                        " did not call through to super.onDestroy()");
4162                }
4163                if (r.window != null) {
4164                    r.window.closeAllPanels();
4165                }
4166            } catch (SuperNotCalledException e) {
4167                throw e;
4168            } catch (Exception e) {
4169                if (!mInstrumentation.onException(r.activity, e)) {
4170                    throw new RuntimeException(
4171                            "Unable to destroy activity " + safeToComponentShortString(r.intent)
4172                            + ": " + e.toString(), e);
4173                }
4174            }
4175        }
4176        mActivities.remove(token);
4177        StrictMode.decrementExpectedActivityCount(activityClass);
4178        return r;
4179    }
4180
4181    private static String safeToComponentShortString(Intent intent) {
4182        ComponentName component = intent.getComponent();
4183        return component == null ? "[Unknown]" : component.toShortString();
4184    }
4185
4186    private void handleDestroyActivity(IBinder token, boolean finishing,
4187            int configChanges, boolean getNonConfigInstance) {
4188        ActivityClientRecord r = performDestroyActivity(token, finishing,
4189                configChanges, getNonConfigInstance);
4190        if (r != null) {
4191            cleanUpPendingRemoveWindows(r, finishing);
4192            WindowManager wm = r.activity.getWindowManager();
4193            View v = r.activity.mDecor;
4194            if (v != null) {
4195                if (r.activity.mVisibleFromServer) {
4196                    mNumVisibleActivities--;
4197                }
4198                IBinder wtoken = v.getWindowToken();
4199                if (r.activity.mWindowAdded) {
4200                    if (r.onlyLocalRequest || r.mPreserveWindow) {
4201                        // Hold off on removing this until the new activity's
4202                        // window is being added.
4203                        r.mPendingRemoveWindow = r.window;
4204                        r.mPendingRemoveWindowManager = wm;
4205                        if (r.mPreserveWindow) {
4206                            // We can only keep the part of the view hierarchy that we control,
4207                            // everything else must be removed, because it might not be able to
4208                            // behave properly when activity is relaunching.
4209                            r.window.clearContentView();
4210                        }
4211                    } else {
4212                        wm.removeViewImmediate(v);
4213                    }
4214                }
4215                if (wtoken != null && r.mPendingRemoveWindow == null) {
4216                    WindowManagerGlobal.getInstance().closeAll(wtoken,
4217                            r.activity.getClass().getName(), "Activity");
4218                }
4219                r.activity.mDecor = null;
4220            }
4221            if (r.mPendingRemoveWindow == null) {
4222                // If we are delaying the removal of the activity window, then
4223                // we can't clean up all windows here.  Note that we can't do
4224                // so later either, which means any windows that aren't closed
4225                // by the app will leak.  Well we try to warning them a lot
4226                // about leaking windows, because that is a bug, so if they are
4227                // using this recreate facility then they get to live with leaks.
4228                WindowManagerGlobal.getInstance().closeAll(token,
4229                        r.activity.getClass().getName(), "Activity");
4230            }
4231
4232            // Mocked out contexts won't be participating in the normal
4233            // process lifecycle, but if we're running with a proper
4234            // ApplicationContext we need to have it tear down things
4235            // cleanly.
4236            Context c = r.activity.getBaseContext();
4237            if (c instanceof ContextImpl) {
4238                ((ContextImpl) c).scheduleFinalCleanup(
4239                        r.activity.getClass().getName(), "Activity");
4240            }
4241        }
4242        if (finishing) {
4243            try {
4244                ActivityManagerNative.getDefault().activityDestroyed(token);
4245            } catch (RemoteException ex) {
4246                throw ex.rethrowFromSystemServer();
4247            }
4248        }
4249        mSomeActivitiesChanged = true;
4250    }
4251
4252    /**
4253     * @param preserveWindow Whether the activity should try to reuse the window it created,
4254     *                        including the decor view after the relaunch.
4255     */
4256    public final void requestRelaunchActivity(IBinder token,
4257            List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents,
4258            int configChanges, boolean notResumed, Configuration config,
4259            Configuration overrideConfig, boolean fromServer, boolean preserveWindow) {
4260        ActivityClientRecord target = null;
4261
4262        synchronized (mResourcesManager) {
4263            for (int i=0; i<mRelaunchingActivities.size(); i++) {
4264                ActivityClientRecord r = mRelaunchingActivities.get(i);
4265                if (DEBUG_ORDER) Slog.d(TAG, "requestRelaunchActivity: " + this + ", trying: " + r);
4266                if (r.token == token) {
4267                    target = r;
4268                    if (pendingResults != null) {
4269                        if (r.pendingResults != null) {
4270                            r.pendingResults.addAll(pendingResults);
4271                        } else {
4272                            r.pendingResults = pendingResults;
4273                        }
4274                    }
4275                    if (pendingNewIntents != null) {
4276                        if (r.pendingIntents != null) {
4277                            r.pendingIntents.addAll(pendingNewIntents);
4278                        } else {
4279                            r.pendingIntents = pendingNewIntents;
4280                        }
4281                    }
4282
4283                    // For each relaunch request, activity manager expects an answer
4284                    if (!r.onlyLocalRequest && fromServer) {
4285                        try {
4286                            ActivityManagerNative.getDefault().activityRelaunched(token);
4287                        } catch (RemoteException e) {
4288                            throw e.rethrowFromSystemServer();
4289                        }
4290                    }
4291                    break;
4292                }
4293            }
4294
4295            if (target == null) {
4296                if (DEBUG_ORDER) Slog.d(TAG, "requestRelaunchActivity: target is null, fromServer:"
4297                        + fromServer);
4298                target = new ActivityClientRecord();
4299                target.token = token;
4300                target.pendingResults = pendingResults;
4301                target.pendingIntents = pendingNewIntents;
4302                target.mPreserveWindow = preserveWindow;
4303                if (!fromServer) {
4304                    final ActivityClientRecord existing = mActivities.get(token);
4305                    if (DEBUG_ORDER) Slog.d(TAG, "requestRelaunchActivity: " + existing);
4306                    if (existing != null) {
4307                        if (DEBUG_ORDER) Slog.d(TAG, "requestRelaunchActivity: paused= "
4308                                + existing.paused);;
4309                        target.startsNotResumed = existing.paused;
4310                        target.overrideConfig = existing.overrideConfig;
4311                    }
4312                    target.onlyLocalRequest = true;
4313                }
4314                mRelaunchingActivities.add(target);
4315                sendMessage(H.RELAUNCH_ACTIVITY, target);
4316            }
4317
4318            if (fromServer) {
4319                target.startsNotResumed = notResumed;
4320                target.onlyLocalRequest = false;
4321            }
4322            if (config != null) {
4323                target.createdConfig = config;
4324            }
4325            if (overrideConfig != null) {
4326                target.overrideConfig = overrideConfig;
4327            }
4328            target.pendingConfigChanges |= configChanges;
4329            target.relaunchSeq = getLifecycleSeq();
4330        }
4331        if (DEBUG_ORDER) Slog.d(TAG, "relaunchActivity " + ActivityThread.this + ", target "
4332                + target + " operation received seq: " + target.relaunchSeq);
4333    }
4334
4335    private void handleRelaunchActivity(ActivityClientRecord tmp) {
4336        // If we are getting ready to gc after going to the background, well
4337        // we are back active so skip it.
4338        unscheduleGcIdler();
4339        mSomeActivitiesChanged = true;
4340
4341        Configuration changedConfig = null;
4342        int configChanges = 0;
4343
4344        // First: make sure we have the most recent configuration and most
4345        // recent version of the activity, or skip it if some previous call
4346        // had taken a more recent version.
4347        synchronized (mResourcesManager) {
4348            int N = mRelaunchingActivities.size();
4349            IBinder token = tmp.token;
4350            tmp = null;
4351            for (int i=0; i<N; i++) {
4352                ActivityClientRecord r = mRelaunchingActivities.get(i);
4353                if (r.token == token) {
4354                    tmp = r;
4355                    configChanges |= tmp.pendingConfigChanges;
4356                    mRelaunchingActivities.remove(i);
4357                    i--;
4358                    N--;
4359                }
4360            }
4361
4362            if (tmp == null) {
4363                if (DEBUG_CONFIGURATION) Slog.v(TAG, "Abort, activity not relaunching!");
4364                return;
4365            }
4366
4367            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Relaunching activity "
4368                    + tmp.token + " with configChanges=0x"
4369                    + Integer.toHexString(configChanges));
4370
4371            if (mPendingConfiguration != null) {
4372                changedConfig = mPendingConfiguration;
4373                mPendingConfiguration = null;
4374            }
4375        }
4376
4377        if (tmp.lastProcessedSeq > tmp.relaunchSeq) {
4378            Slog.wtf(TAG, "For some reason target: " + tmp + " has lower sequence: "
4379                    + tmp.relaunchSeq + " than current sequence: " + tmp.lastProcessedSeq);
4380        } else {
4381            tmp.lastProcessedSeq = tmp.relaunchSeq;
4382        }
4383        if (tmp.createdConfig != null) {
4384            // If the activity manager is passing us its current config,
4385            // assume that is really what we want regardless of what we
4386            // may have pending.
4387            if (mConfiguration == null
4388                    || (tmp.createdConfig.isOtherSeqNewer(mConfiguration)
4389                            && mConfiguration.diff(tmp.createdConfig) != 0)) {
4390                if (changedConfig == null
4391                        || tmp.createdConfig.isOtherSeqNewer(changedConfig)) {
4392                    changedConfig = tmp.createdConfig;
4393                }
4394            }
4395        }
4396
4397        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Relaunching activity "
4398                + tmp.token + ": changedConfig=" + changedConfig);
4399
4400        // If there was a pending configuration change, execute it first.
4401        if (changedConfig != null) {
4402            mCurDefaultDisplayDpi = changedConfig.densityDpi;
4403            updateDefaultDensity();
4404            handleConfigurationChanged(changedConfig, null);
4405        }
4406
4407        ActivityClientRecord r = mActivities.get(tmp.token);
4408        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handling relaunch of " + r);
4409        if (r == null) {
4410            if (!tmp.onlyLocalRequest) {
4411                try {
4412                    ActivityManagerNative.getDefault().activityRelaunched(tmp.token);
4413                } catch (RemoteException e) {
4414                    throw e.rethrowFromSystemServer();
4415                }
4416            }
4417            return;
4418        }
4419
4420        r.activity.mConfigChangeFlags |= configChanges;
4421        r.onlyLocalRequest = tmp.onlyLocalRequest;
4422        r.mPreserveWindow = tmp.mPreserveWindow;
4423        r.lastProcessedSeq = tmp.lastProcessedSeq;
4424        r.relaunchSeq = tmp.relaunchSeq;
4425        Intent currentIntent = r.activity.mIntent;
4426
4427        r.activity.mChangingConfigurations = true;
4428
4429        // If we are preserving the main window across relaunches we would also like to preserve
4430        // the children. However the client side view system does not support preserving
4431        // the child views so we notify the window manager to expect these windows to
4432        // be replaced and defer requests to destroy or hide them. This way we can achieve
4433        // visual continuity. It's important that we do this here prior to pause and destroy
4434        // as that is when we may hide or remove the child views.
4435        try {
4436            if (r.mPreserveWindow) {
4437                WindowManagerGlobal.getWindowSession().prepareToReplaceChildren(r.token);
4438            }
4439        } catch (RemoteException e) {
4440            throw e.rethrowFromSystemServer();
4441        }
4442
4443
4444        // Need to ensure state is saved.
4445        if (!r.paused) {
4446            performPauseActivity(r.token, false, r.isPreHoneycomb(), "handleRelaunchActivity");
4447        }
4448        if (r.state == null && !r.stopped && !r.isPreHoneycomb()) {
4449            callCallActivityOnSaveInstanceState(r);
4450        }
4451
4452        handleDestroyActivity(r.token, false, configChanges, true);
4453
4454        r.activity = null;
4455        r.window = null;
4456        r.hideForNow = false;
4457        r.nextIdle = null;
4458        // Merge any pending results and pending intents; don't just replace them
4459        if (tmp.pendingResults != null) {
4460            if (r.pendingResults == null) {
4461                r.pendingResults = tmp.pendingResults;
4462            } else {
4463                r.pendingResults.addAll(tmp.pendingResults);
4464            }
4465        }
4466        if (tmp.pendingIntents != null) {
4467            if (r.pendingIntents == null) {
4468                r.pendingIntents = tmp.pendingIntents;
4469            } else {
4470                r.pendingIntents.addAll(tmp.pendingIntents);
4471            }
4472        }
4473        r.startsNotResumed = tmp.startsNotResumed;
4474        r.overrideConfig = tmp.overrideConfig;
4475
4476        handleLaunchActivity(r, currentIntent, "handleRelaunchActivity");
4477
4478        if (!tmp.onlyLocalRequest) {
4479            try {
4480                ActivityManagerNative.getDefault().activityRelaunched(r.token);
4481                if (r.window != null) {
4482                    r.window.reportActivityRelaunched();
4483                }
4484            } catch (RemoteException e) {
4485                throw e.rethrowFromSystemServer();
4486            }
4487        }
4488    }
4489
4490    private void callCallActivityOnSaveInstanceState(ActivityClientRecord r) {
4491        r.state = new Bundle();
4492        r.state.setAllowFds(false);
4493        if (r.isPersistable()) {
4494            r.persistentState = new PersistableBundle();
4495            mInstrumentation.callActivityOnSaveInstanceState(r.activity, r.state,
4496                    r.persistentState);
4497        } else {
4498            mInstrumentation.callActivityOnSaveInstanceState(r.activity, r.state);
4499        }
4500    }
4501
4502    ArrayList<ComponentCallbacks2> collectComponentCallbacks(
4503            boolean allActivities, Configuration newConfig) {
4504        ArrayList<ComponentCallbacks2> callbacks
4505                = new ArrayList<ComponentCallbacks2>();
4506
4507        synchronized (mResourcesManager) {
4508            final int NAPP = mAllApplications.size();
4509            for (int i=0; i<NAPP; i++) {
4510                callbacks.add(mAllApplications.get(i));
4511            }
4512            final int NACT = mActivities.size();
4513            for (int i=0; i<NACT; i++) {
4514                ActivityClientRecord ar = mActivities.valueAt(i);
4515                Activity a = ar.activity;
4516                if (a != null) {
4517                    Configuration thisConfig = applyConfigCompatMainThread(
4518                            mCurDefaultDisplayDpi, newConfig,
4519                            ar.packageInfo.getCompatibilityInfo());
4520                    if (!ar.activity.mFinished && (allActivities || !ar.paused)) {
4521                        // If the activity is currently resumed, its configuration
4522                        // needs to change right now.
4523                        callbacks.add(a);
4524                    } else if (thisConfig != null) {
4525                        // Otherwise, we will tell it about the change
4526                        // the next time it is resumed or shown.  Note that
4527                        // the activity manager may, before then, decide the
4528                        // activity needs to be destroyed to handle its new
4529                        // configuration.
4530                        if (DEBUG_CONFIGURATION) {
4531                            Slog.v(TAG, "Setting activity "
4532                                    + ar.activityInfo.name + " newConfig=" + thisConfig);
4533                        }
4534                        ar.newConfig = thisConfig;
4535                    }
4536                }
4537            }
4538            final int NSVC = mServices.size();
4539            for (int i=0; i<NSVC; i++) {
4540                callbacks.add(mServices.valueAt(i));
4541            }
4542        }
4543        synchronized (mProviderMap) {
4544            final int NPRV = mLocalProviders.size();
4545            for (int i=0; i<NPRV; i++) {
4546                callbacks.add(mLocalProviders.valueAt(i).mLocalProvider);
4547            }
4548        }
4549
4550        return callbacks;
4551    }
4552
4553    /**
4554     * Updates the configuration for an Activity. The ActivityClientRecord's
4555     * {@link ActivityClientRecord#overrideConfig} is used to compute the final Configuration for
4556     * that Activity. {@link ActivityClientRecord#tmpConfig} is used as a temporary for delivering
4557     * the updated Configuration.
4558     * @param r ActivityClientRecord representing the Activity.
4559     * @param newBaseConfig The new configuration to use. This may be augmented with
4560     *                      {@link ActivityClientRecord#overrideConfig}.
4561     * @param reportToActivity true if the change should be reported to the Activity's callback.
4562     */
4563    private void performConfigurationChangedForActivity(ActivityClientRecord r,
4564                                                        Configuration newBaseConfig,
4565                                                        boolean reportToActivity) {
4566        r.tmpConfig.setTo(newBaseConfig);
4567        if (r.overrideConfig != null) {
4568            r.tmpConfig.updateFrom(r.overrideConfig);
4569        }
4570        performConfigurationChanged(r.activity, r.token, r.tmpConfig, r.overrideConfig,
4571                reportToActivity);
4572        freeTextLayoutCachesIfNeeded(r.activity.mCurrentConfig.diff(r.tmpConfig));
4573    }
4574
4575    /**
4576     * Decides whether to update an Activity's configuration and whether to tell the
4577     * Activity/Component about it.
4578     * @param cb The component callback to notify of configuration change.
4579     * @param activityToken The Activity binder token for which this configuration change happened.
4580     *                      If the change is global, this is null.
4581     * @param newConfig The new configuration.
4582     * @param overrideConfig The override config that differentiates the Activity's configuration
4583     *                       from the base global configuration.
4584     * @param reportToActivity Notify the Activity of the change.
4585     */
4586    private void performConfigurationChanged(ComponentCallbacks2 cb,
4587                                             IBinder activityToken,
4588                                             Configuration newConfig,
4589                                             Configuration overrideConfig,
4590                                             boolean reportToActivity) {
4591        // Only for Activity objects, check that they actually call up to their
4592        // superclass implementation.  ComponentCallbacks2 is an interface, so
4593        // we check the runtime type and act accordingly.
4594        Activity activity = (cb instanceof Activity) ? (Activity) cb : null;
4595        if (activity != null) {
4596            activity.mCalled = false;
4597        }
4598
4599        boolean shouldChangeConfig = false;
4600        if ((activity == null) || (activity.mCurrentConfig == null)) {
4601            shouldChangeConfig = true;
4602        } else {
4603
4604            // If the new config is the same as the config this Activity
4605            // is already running with then don't bother calling
4606            // onConfigurationChanged
4607            int diff = activity.mCurrentConfig.diff(newConfig);
4608            if (diff != 0) {
4609                // If this activity doesn't handle any of the config changes then don't bother
4610                // calling onConfigurationChanged as we're going to destroy it.
4611                // Except in the case where the configuration changed on the activity manager side,
4612                // but wasn't big enough to cause a resource change so the activity wasn't destroyed.
4613                // In this case we still want to change the configuration of the activity but not
4614                // report it to the app.
4615                if ((~activity.mActivityInfo.getRealConfigChanged() & diff) == 0
4616                        || !reportToActivity) {
4617                    shouldChangeConfig = true;
4618                }
4619            }
4620        }
4621
4622        if (DEBUG_CONFIGURATION) {
4623            Slog.v(TAG, "Config callback " + cb + ": shouldChangeConfig=" + shouldChangeConfig);
4624        }
4625
4626        if (shouldChangeConfig) {
4627            if (activityToken != null) {
4628                // We only update an Activity's configuration if this is not a global
4629                // configuration change. This must also be done before the callback,
4630                // or else we violate the contract that the new resources are available
4631                // in {@link ComponentCallbacks2#onConfigurationChanged(Configuration)}.
4632                mResourcesManager.updateResourcesForActivity(activityToken, overrideConfig);
4633            }
4634
4635            if (reportToActivity) {
4636                Configuration configToReport = newConfig;
4637
4638                if (cb instanceof ContextThemeWrapper) {
4639                    // ContextThemeWrappers may override the configuration for that context.
4640                    // We must check and apply any overrides defined.
4641                    ContextThemeWrapper contextThemeWrapper = (ContextThemeWrapper) cb;
4642                    final Configuration localOverrideConfig =
4643                            contextThemeWrapper.getOverrideConfiguration();
4644                    if (localOverrideConfig != null) {
4645                        configToReport = new Configuration(newConfig);
4646                        configToReport.updateFrom(localOverrideConfig);
4647                    }
4648                }
4649
4650                cb.onConfigurationChanged(configToReport);
4651            }
4652
4653            if (activity != null) {
4654                if (reportToActivity && !activity.mCalled) {
4655                    throw new SuperNotCalledException(
4656                            "Activity " + activity.getLocalClassName() +
4657                            " did not call through to super.onConfigurationChanged()");
4658                }
4659                activity.mConfigChangeFlags = 0;
4660                activity.mCurrentConfig = new Configuration(newConfig);
4661            }
4662        }
4663    }
4664
4665    public final void applyConfigurationToResources(Configuration config) {
4666        synchronized (mResourcesManager) {
4667            mResourcesManager.applyConfigurationToResourcesLocked(config, null);
4668        }
4669    }
4670
4671    final Configuration applyCompatConfiguration(int displayDensity) {
4672        Configuration config = mConfiguration;
4673        if (mCompatConfiguration == null) {
4674            mCompatConfiguration = new Configuration();
4675        }
4676        mCompatConfiguration.setTo(mConfiguration);
4677        if (mResourcesManager.applyCompatConfigurationLocked(displayDensity,
4678                mCompatConfiguration)) {
4679            config = mCompatConfiguration;
4680        }
4681        return config;
4682    }
4683
4684    final void handleConfigurationChanged(Configuration config, CompatibilityInfo compat) {
4685
4686        int configDiff = 0;
4687
4688        synchronized (mResourcesManager) {
4689            if (mPendingConfiguration != null) {
4690                if (!mPendingConfiguration.isOtherSeqNewer(config)) {
4691                    config = mPendingConfiguration;
4692                    mCurDefaultDisplayDpi = config.densityDpi;
4693                    updateDefaultDensity();
4694                }
4695                mPendingConfiguration = null;
4696            }
4697
4698            if (config == null) {
4699                return;
4700            }
4701
4702            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handle configuration changed: "
4703                    + config);
4704
4705            mResourcesManager.applyConfigurationToResourcesLocked(config, compat);
4706
4707            if (mConfiguration == null) {
4708                mConfiguration = new Configuration();
4709            }
4710            if (!mConfiguration.isOtherSeqNewer(config) && compat == null) {
4711                return;
4712            }
4713
4714            configDiff = mConfiguration.updateFrom(config);
4715            config = applyCompatConfiguration(mCurDefaultDisplayDpi);
4716
4717            final Theme systemTheme = getSystemContext().getTheme();
4718            if ((systemTheme.getChangingConfigurations() & configDiff) != 0) {
4719                systemTheme.rebase();
4720            }
4721        }
4722
4723        ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(false, config);
4724
4725        freeTextLayoutCachesIfNeeded(configDiff);
4726
4727        if (callbacks != null) {
4728            final int N = callbacks.size();
4729            for (int i=0; i<N; i++) {
4730                ComponentCallbacks2 cb = callbacks.get(i);
4731                if (cb instanceof Activity) {
4732                    // If callback is an Activity - call corresponding method to consider override
4733                    // config and avoid onConfigurationChanged if it hasn't changed.
4734                    Activity a = (Activity) cb;
4735                    performConfigurationChangedForActivity(mActivities.get(a.getActivityToken()),
4736                            config, REPORT_TO_ACTIVITY);
4737                } else {
4738                    performConfigurationChanged(cb, null, config, null, REPORT_TO_ACTIVITY);
4739                }
4740            }
4741        }
4742    }
4743
4744    static void freeTextLayoutCachesIfNeeded(int configDiff) {
4745        if (configDiff != 0) {
4746            // Ask text layout engine to free its caches if there is a locale change
4747            boolean hasLocaleConfigChange = ((configDiff & ActivityInfo.CONFIG_LOCALE) != 0);
4748            if (hasLocaleConfigChange) {
4749                Canvas.freeTextLayoutCaches();
4750                if (DEBUG_CONFIGURATION) Slog.v(TAG, "Cleared TextLayout Caches");
4751            }
4752        }
4753    }
4754
4755    final void handleActivityConfigurationChanged(ActivityConfigChangeData data,
4756            boolean reportToActivity) {
4757        ActivityClientRecord r = mActivities.get(data.activityToken);
4758        if (r == null || r.activity == null) {
4759            return;
4760        }
4761
4762        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handle activity config changed: "
4763                + r.activityInfo.name + ", with callback=" + reportToActivity);
4764
4765        r.overrideConfig = data.overrideConfig;
4766        performConfigurationChangedForActivity(r, mCompatConfiguration, reportToActivity);
4767        mSomeActivitiesChanged = true;
4768    }
4769
4770    final void handleProfilerControl(boolean start, ProfilerInfo profilerInfo, int profileType) {
4771        if (start) {
4772            try {
4773                switch (profileType) {
4774                    default:
4775                        mProfiler.setProfiler(profilerInfo);
4776                        mProfiler.startProfiling();
4777                        break;
4778                }
4779            } catch (RuntimeException e) {
4780                Slog.w(TAG, "Profiling failed on path " + profilerInfo.profileFile
4781                        + " -- can the process access this path?");
4782            } finally {
4783                try {
4784                    profilerInfo.profileFd.close();
4785                } catch (IOException e) {
4786                    Slog.w(TAG, "Failure closing profile fd", e);
4787                }
4788            }
4789        } else {
4790            switch (profileType) {
4791                default:
4792                    mProfiler.stopProfiling();
4793                    break;
4794            }
4795        }
4796    }
4797
4798    /**
4799     * Public entrypoint to stop profiling. This is required to end profiling when the app crashes,
4800     * so that profiler data won't be lost.
4801     *
4802     * @hide
4803     */
4804    public void stopProfiling() {
4805        mProfiler.stopProfiling();
4806    }
4807
4808    static final void handleDumpHeap(boolean managed, DumpHeapData dhd) {
4809        if (managed) {
4810            try {
4811                Debug.dumpHprofData(dhd.path, dhd.fd.getFileDescriptor());
4812            } catch (IOException e) {
4813                Slog.w(TAG, "Managed heap dump failed on path " + dhd.path
4814                        + " -- can the process access this path?");
4815            } finally {
4816                try {
4817                    dhd.fd.close();
4818                } catch (IOException e) {
4819                    Slog.w(TAG, "Failure closing profile fd", e);
4820                }
4821            }
4822        } else {
4823            Debug.dumpNativeHeap(dhd.fd.getFileDescriptor());
4824        }
4825        try {
4826            ActivityManagerNative.getDefault().dumpHeapFinished(dhd.path);
4827        } catch (RemoteException e) {
4828            throw e.rethrowFromSystemServer();
4829        }
4830    }
4831
4832    final void handleDispatchPackageBroadcast(int cmd, String[] packages) {
4833        boolean hasPkgInfo = false;
4834        switch (cmd) {
4835            case IApplicationThread.PACKAGE_REMOVED:
4836            case IApplicationThread.PACKAGE_REMOVED_DONT_KILL:
4837            {
4838                final boolean killApp = cmd == IApplicationThread.PACKAGE_REMOVED;
4839                if (packages == null) {
4840                    break;
4841                }
4842                synchronized (mResourcesManager) {
4843                    for (int i = packages.length - 1; i >= 0; i--) {
4844                        if (!hasPkgInfo) {
4845                            WeakReference<LoadedApk> ref = mPackages.get(packages[i]);
4846                            if (ref != null && ref.get() != null) {
4847                                hasPkgInfo = true;
4848                            } else {
4849                                ref = mResourcePackages.get(packages[i]);
4850                                if (ref != null && ref.get() != null) {
4851                                    hasPkgInfo = true;
4852                                }
4853                            }
4854                        }
4855                        if (killApp) {
4856                            mPackages.remove(packages[i]);
4857                            mResourcePackages.remove(packages[i]);
4858                        }
4859                    }
4860                }
4861                break;
4862            }
4863            case IApplicationThread.PACKAGE_REPLACED:
4864            {
4865                if (packages == null) {
4866                    break;
4867                }
4868                synchronized (mResourcesManager) {
4869                    for (int i = packages.length - 1; i >= 0; i--) {
4870                        WeakReference<LoadedApk> ref = mPackages.get(packages[i]);
4871                        LoadedApk pkgInfo = ref != null ? ref.get() : null;
4872                        if (pkgInfo != null) {
4873                            hasPkgInfo = true;
4874                        } else {
4875                            ref = mResourcePackages.get(packages[i]);
4876                            pkgInfo = ref != null ? ref.get() : null;
4877                            if (pkgInfo != null) {
4878                                hasPkgInfo = true;
4879                            }
4880                        }
4881                        // If the package is being replaced, yet it still has a valid
4882                        // LoadedApk object, the package was updated with _DONT_KILL.
4883                        // Adjust it's internal references to the application info and
4884                        // resources.
4885                        if (pkgInfo != null) {
4886                            try {
4887                                final String packageName = packages[i];
4888                                final ApplicationInfo aInfo =
4889                                        sPackageManager.getApplicationInfo(
4890                                                packageName,
4891                                                0 /*flags*/,
4892                                                UserHandle.myUserId());
4893
4894                                if (mActivities.size() > 0) {
4895                                    for (ActivityClientRecord ar : mActivities.values()) {
4896                                        if (ar.activityInfo.applicationInfo.packageName
4897                                                .equals(packageName)) {
4898                                            ar.activityInfo.applicationInfo = aInfo;
4899                                            ar.packageInfo = pkgInfo;
4900                                        }
4901                                    }
4902                                }
4903                                final List<String> oldPaths =
4904                                        sPackageManager.getPreviousCodePaths(packageName);
4905                                pkgInfo.updateApplicationInfo(aInfo, oldPaths);
4906                            } catch (RemoteException e) {
4907                            }
4908                        }
4909                    }
4910                }
4911                break;
4912            }
4913        }
4914        ApplicationPackageManager.handlePackageBroadcast(cmd, packages, hasPkgInfo);
4915    }
4916
4917    final void handleLowMemory() {
4918        ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(true, null);
4919
4920        final int N = callbacks.size();
4921        for (int i=0; i<N; i++) {
4922            callbacks.get(i).onLowMemory();
4923        }
4924
4925        // Ask SQLite to free up as much memory as it can, mostly from its page caches.
4926        if (Process.myUid() != Process.SYSTEM_UID) {
4927            int sqliteReleased = SQLiteDatabase.releaseMemory();
4928            EventLog.writeEvent(SQLITE_MEM_RELEASED_EVENT_LOG_TAG, sqliteReleased);
4929        }
4930
4931        // Ask graphics to free up as much as possible (font/image caches)
4932        Canvas.freeCaches();
4933
4934        // Ask text layout engine to free also as much as possible
4935        Canvas.freeTextLayoutCaches();
4936
4937        BinderInternal.forceGc("mem");
4938    }
4939
4940    final void handleTrimMemory(int level) {
4941        if (DEBUG_MEMORY_TRIM) Slog.v(TAG, "Trimming memory to level: " + level);
4942
4943        ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(true, null);
4944
4945        final int N = callbacks.size();
4946        for (int i = 0; i < N; i++) {
4947            callbacks.get(i).onTrimMemory(level);
4948        }
4949
4950        WindowManagerGlobal.getInstance().trimMemory(level);
4951    }
4952
4953    private void setupGraphicsSupport(LoadedApk info, File cacheDir) {
4954        if (Process.isIsolated()) {
4955            // Isolated processes aren't going to do UI.
4956            return;
4957        }
4958        try {
4959            int uid = Process.myUid();
4960            String[] packages = getPackageManager().getPackagesForUid(uid);
4961
4962            // If there are several packages in this application we won't
4963            // initialize the graphics disk caches
4964            if (packages != null && packages.length == 1) {
4965                ThreadedRenderer.setupDiskCache(cacheDir);
4966                RenderScriptCacheDir.setupDiskCache(cacheDir);
4967            }
4968        } catch (RemoteException e) {
4969            throw e.rethrowFromSystemServer();
4970        }
4971    }
4972
4973    // Keep in sync with installd (frameworks/native/cmds/installd/commands.cpp).
4974    private static File getPrimaryProfileFile(String packageName) {
4975        File profileDir = Environment.getDataProfilesDePackageDirectory(
4976                UserHandle.myUserId(), packageName);
4977        return new File(profileDir, "primary.prof");
4978    }
4979
4980    private static void setupJitProfileSupport(LoadedApk loadedApk, File cacheDir) {
4981        if (!SystemProperties.getBoolean("dalvik.vm.usejitprofiles", false)) {
4982            return;
4983        }
4984        final ApplicationInfo appInfo = loadedApk.getApplicationInfo();
4985        final List<String> codePaths = new ArrayList<>();
4986        if ((appInfo.flags & ApplicationInfo.FLAG_HAS_CODE) != 0) {
4987            codePaths.add(appInfo.sourceDir);
4988        }
4989        if (appInfo.splitSourceDirs != null) {
4990            Collections.addAll(codePaths, appInfo.splitSourceDirs);
4991        }
4992
4993        if (codePaths.isEmpty()) {
4994            // If there are no code paths there's no need to setup a profile file and register with
4995            // the runtime,
4996            return;
4997        }
4998
4999        final File profileFile = getPrimaryProfileFile(loadedApk.mPackageName);
5000        if (!profileFile.exists()) {
5001            FileDescriptor fd = null;
5002            try {
5003                final int permissions = 0600;  // read-write for user.
5004                fd = Os.open(profileFile.getAbsolutePath(), OsConstants.O_CREAT, permissions);
5005                Os.fchmod(fd, permissions);
5006                Os.fchown(fd, appInfo.uid, appInfo.uid);
5007            } catch (ErrnoException e) {
5008                Log.v(TAG, "Unable to create jit profile file "
5009                        + profileFile + ": " + e.getMessage());
5010                try {
5011                    Os.unlink(profileFile.getAbsolutePath());
5012                } catch (ErrnoException unlinkErr) {
5013                    if (unlinkErr.errno != OsConstants.ENOENT) {
5014                        Log.v(TAG, "Unable to unlink jit profile file "
5015                                + profileFile + ": " + unlinkErr.getMessage());
5016                    }
5017                }
5018                return;
5019            } finally {
5020                IoUtils.closeQuietly(fd);
5021            }
5022        }
5023
5024        final File foreignDexProfilesFile =
5025                Environment.getDataProfilesDeForeignDexDirectory(UserHandle.myUserId());
5026        String foreignDexProfilesPath = null;
5027        if (!foreignDexProfilesFile.exists()) {
5028            Log.v(TAG, "ForeignDexProfilesPath does not exists:" +
5029                    foreignDexProfilesFile.getPath());
5030        } else {
5031            foreignDexProfilesPath = foreignDexProfilesFile.getAbsolutePath();
5032        }
5033        VMRuntime.registerAppInfo(profileFile.getAbsolutePath(), appInfo.dataDir,
5034                codePaths.toArray(new String[codePaths.size()]), foreignDexProfilesPath);
5035    }
5036
5037    private void updateDefaultDensity() {
5038        final int densityDpi = mCurDefaultDisplayDpi;
5039        if (!mDensityCompatMode
5040                && densityDpi != Configuration.DENSITY_DPI_UNDEFINED
5041                && densityDpi != DisplayMetrics.DENSITY_DEVICE) {
5042            DisplayMetrics.DENSITY_DEVICE = densityDpi;
5043            Bitmap.setDefaultDensity(densityDpi);
5044        }
5045    }
5046
5047    private void handleBindApplication(AppBindData data) {
5048        // Register the UI Thread as a sensitive thread to the runtime.
5049        VMRuntime.registerSensitiveThread();
5050        if (data.trackAllocation) {
5051            DdmVmInternal.enableRecentAllocations(true);
5052        }
5053
5054        // Note when this process has started.
5055        Process.setStartTimes(SystemClock.elapsedRealtime(), SystemClock.uptimeMillis());
5056
5057        mBoundApplication = data;
5058        mConfiguration = new Configuration(data.config);
5059        mCompatConfiguration = new Configuration(data.config);
5060
5061        mProfiler = new Profiler();
5062        if (data.initProfilerInfo != null) {
5063            mProfiler.profileFile = data.initProfilerInfo.profileFile;
5064            mProfiler.profileFd = data.initProfilerInfo.profileFd;
5065            mProfiler.samplingInterval = data.initProfilerInfo.samplingInterval;
5066            mProfiler.autoStopProfiler = data.initProfilerInfo.autoStopProfiler;
5067        }
5068
5069        // send up app name; do this *before* waiting for debugger
5070        Process.setArgV0(data.processName);
5071        android.ddm.DdmHandleAppName.setAppName(data.processName,
5072                                                UserHandle.myUserId());
5073
5074        if (data.persistent) {
5075            // Persistent processes on low-memory devices do not get to
5076            // use hardware accelerated drawing, since this can add too much
5077            // overhead to the process.
5078            if (!ActivityManager.isHighEndGfx()) {
5079                ThreadedRenderer.disable(false);
5080            }
5081        }
5082
5083        if (mProfiler.profileFd != null) {
5084            mProfiler.startProfiling();
5085        }
5086
5087        // If the app is Honeycomb MR1 or earlier, switch its AsyncTask
5088        // implementation to use the pool executor.  Normally, we use the
5089        // serialized executor as the default. This has to happen in the
5090        // main thread so the main looper is set right.
5091        if (data.appInfo.targetSdkVersion <= android.os.Build.VERSION_CODES.HONEYCOMB_MR1) {
5092            AsyncTask.setDefaultExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
5093        }
5094
5095        Message.updateCheckRecycle(data.appInfo.targetSdkVersion);
5096
5097        /*
5098         * Before spawning a new process, reset the time zone to be the system time zone.
5099         * This needs to be done because the system time zone could have changed after the
5100         * the spawning of this process. Without doing this this process would have the incorrect
5101         * system time zone.
5102         */
5103        TimeZone.setDefault(null);
5104
5105        data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
5106
5107        /**
5108         * Switch this process to density compatibility mode if needed.
5109         */
5110        if ((data.appInfo.flags&ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES)
5111                == 0) {
5112            mDensityCompatMode = true;
5113            Bitmap.setDefaultDensity(DisplayMetrics.DENSITY_DEFAULT);
5114        }
5115        updateDefaultDensity();
5116
5117        final boolean is24Hr = "24".equals(mCoreSettings.getString(Settings.System.TIME_12_24));
5118        DateFormat.set24HourTimePref(is24Hr);
5119
5120        View.mDebugViewAttributes =
5121                mCoreSettings.getInt(Settings.Global.DEBUG_VIEW_ATTRIBUTES, 0) != 0;
5122
5123        /**
5124         * For system applications on userdebug/eng builds, log stack
5125         * traces of disk and network access to dropbox for analysis.
5126         */
5127        if ((data.appInfo.flags &
5128             (ApplicationInfo.FLAG_SYSTEM |
5129              ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0) {
5130            StrictMode.conditionallyEnableDebugLogging();
5131        }
5132
5133        /**
5134         * For apps targetting Honeycomb or later, we don't allow network usage
5135         * on the main event loop / UI thread. This is what ultimately throws
5136         * {@link NetworkOnMainThreadException}.
5137         */
5138        if (data.appInfo.targetSdkVersion >= Build.VERSION_CODES.HONEYCOMB) {
5139            StrictMode.enableDeathOnNetwork();
5140        }
5141
5142        /**
5143         * For apps targetting N or later, we don't allow file:// Uri exposure.
5144         * This is what ultimately throws {@link FileUriExposedException}.
5145         */
5146        if (data.appInfo.targetSdkVersion >= Build.VERSION_CODES.N) {
5147            StrictMode.enableDeathOnFileUriExposure();
5148        }
5149
5150        NetworkSecurityPolicy.getInstance().setCleartextTrafficPermitted(
5151                (data.appInfo.flags & ApplicationInfo.FLAG_USES_CLEARTEXT_TRAFFIC) != 0);
5152
5153        if (data.debugMode != IApplicationThread.DEBUG_OFF) {
5154            // XXX should have option to change the port.
5155            Debug.changeDebugPort(8100);
5156            if (data.debugMode == IApplicationThread.DEBUG_WAIT) {
5157                Slog.w(TAG, "Application " + data.info.getPackageName()
5158                      + " is waiting for the debugger on port 8100...");
5159
5160                IActivityManager mgr = ActivityManagerNative.getDefault();
5161                try {
5162                    mgr.showWaitingForDebugger(mAppThread, true);
5163                } catch (RemoteException ex) {
5164                    throw ex.rethrowFromSystemServer();
5165                }
5166
5167                Debug.waitForDebugger();
5168
5169                try {
5170                    mgr.showWaitingForDebugger(mAppThread, false);
5171                } catch (RemoteException ex) {
5172                    throw ex.rethrowFromSystemServer();
5173                }
5174
5175            } else {
5176                Slog.w(TAG, "Application " + data.info.getPackageName()
5177                      + " can be debugged on port 8100...");
5178            }
5179        }
5180
5181        // Allow application-generated systrace messages if we're debuggable.
5182        boolean isAppDebuggable = (data.appInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
5183        Trace.setAppTracingAllowed(isAppDebuggable);
5184        if (isAppDebuggable && data.enableBinderTracking) {
5185            Binder.enableTracing();
5186        }
5187
5188        /**
5189         * Initialize the default http proxy in this process for the reasons we set the time zone.
5190         */
5191        final IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE);
5192        if (b != null) {
5193            // In pre-boot mode (doing initial launch to collect password), not
5194            // all system is up.  This includes the connectivity service, so don't
5195            // crash if we can't get it.
5196            final IConnectivityManager service = IConnectivityManager.Stub.asInterface(b);
5197            try {
5198                final ProxyInfo proxyInfo = service.getProxyForNetwork(null);
5199                Proxy.setHttpProxySystemProperty(proxyInfo);
5200            } catch (RemoteException e) {
5201                throw e.rethrowFromSystemServer();
5202            }
5203        }
5204
5205        // Instrumentation info affects the class loader, so load it before
5206        // setting up the app context.
5207        final InstrumentationInfo ii;
5208        if (data.instrumentationName != null) {
5209            try {
5210                ii = new ApplicationPackageManager(null, getPackageManager())
5211                        .getInstrumentationInfo(data.instrumentationName, 0);
5212            } catch (PackageManager.NameNotFoundException e) {
5213                throw new RuntimeException(
5214                        "Unable to find instrumentation info for: " + data.instrumentationName);
5215            }
5216
5217            mInstrumentationPackageName = ii.packageName;
5218            mInstrumentationAppDir = ii.sourceDir;
5219            mInstrumentationSplitAppDirs = ii.splitSourceDirs;
5220            mInstrumentationLibDir = ii.nativeLibraryDir;
5221            mInstrumentedAppDir = data.info.getAppDir();
5222            mInstrumentedSplitAppDirs = data.info.getSplitAppDirs();
5223            mInstrumentedLibDir = data.info.getLibDir();
5224        } else {
5225            ii = null;
5226        }
5227
5228        final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);
5229        synchronized (mResourcesManager) {
5230            /*
5231             * Initialize the default locales in this process for the reasons we set the time zone.
5232             *
5233             * We do this through ResourcesManager, since we need to do locale negotiation.
5234             */
5235            mResourcesManager.setDefaultLocalesLocked(data.config.getLocales());
5236
5237            /*
5238             * Update the system configuration since its preloaded and might not
5239             * reflect configuration changes. The configuration object passed
5240             * in AppBindData can be safely assumed to be up to date
5241             */
5242            mResourcesManager.applyConfigurationToResourcesLocked(data.config, data.compatInfo);
5243            mCurDefaultDisplayDpi = data.config.densityDpi;
5244
5245            // This calls mResourcesManager so keep it within the synchronized block.
5246            applyCompatConfiguration(mCurDefaultDisplayDpi);
5247        }
5248
5249        if (!Process.isIsolated() && !"android".equals(appContext.getPackageName())) {
5250            // This cache location probably points at credential-encrypted
5251            // storage which may not be accessible yet; assign it anyway instead
5252            // of pointing at device-encrypted storage.
5253            final File cacheDir = appContext.getCacheDir();
5254            if (cacheDir != null) {
5255                // Provide a usable directory for temporary files
5256                System.setProperty("java.io.tmpdir", cacheDir.getAbsolutePath());
5257            } else {
5258                Log.v(TAG, "Unable to initialize \"java.io.tmpdir\" property "
5259                        + "due to missing cache directory");
5260            }
5261
5262            // Setup a location to store generated/compiled graphics code and
5263            // JIT profiling data. Note that this data is stored in a
5264            // device-protected storage area, so these caches must never contain
5265            // user sensitive user data.
5266            final Context deviceContext = appContext.createDeviceProtectedStorageContext();
5267            final File codeCacheDir = deviceContext.getCodeCacheDir();
5268            if (codeCacheDir != null) {
5269                setupGraphicsSupport(data.info, codeCacheDir);
5270                setupJitProfileSupport(data.info, codeCacheDir);
5271            } else {
5272                Log.e(TAG, "Unable to setupGraphicsSupport and setupJitProfileSupport " +
5273                        "due to missing code-cache directory");
5274            }
5275
5276            // Add the lib dir path to hardware renderer so that vulkan layers
5277            // can be searched for within that directory.
5278            ThreadedRenderer.setLibDir(data.info.getLibDir());
5279        }
5280
5281        // Install the Network Security Config Provider. This must happen before the application
5282        // code is loaded to prevent issues with instances of TLS objects being created before
5283        // the provider is installed.
5284        NetworkSecurityConfigProvider.install(appContext);
5285
5286        // Continue loading instrumentation.
5287        if (ii != null) {
5288            final ApplicationInfo instrApp = new ApplicationInfo();
5289            ii.copyTo(instrApp);
5290            instrApp.initForUser(UserHandle.myUserId());
5291            final LoadedApk pi = getPackageInfo(instrApp, data.compatInfo,
5292                    appContext.getClassLoader(), false, true, false);
5293            final ContextImpl instrContext = ContextImpl.createAppContext(this, pi);
5294
5295            try {
5296                final ClassLoader cl = instrContext.getClassLoader();
5297                mInstrumentation = (Instrumentation)
5298                    cl.loadClass(data.instrumentationName.getClassName()).newInstance();
5299            } catch (Exception e) {
5300                throw new RuntimeException(
5301                    "Unable to instantiate instrumentation "
5302                    + data.instrumentationName + ": " + e.toString(), e);
5303            }
5304
5305            final ComponentName component = new ComponentName(ii.packageName, ii.name);
5306            mInstrumentation.init(this, instrContext, appContext, component,
5307                    data.instrumentationWatcher, data.instrumentationUiAutomationConnection);
5308
5309            if (mProfiler.profileFile != null && !ii.handleProfiling
5310                    && mProfiler.profileFd == null) {
5311                mProfiler.handlingProfiling = true;
5312                final File file = new File(mProfiler.profileFile);
5313                file.getParentFile().mkdirs();
5314                Debug.startMethodTracing(file.toString(), 8 * 1024 * 1024);
5315            }
5316        } else {
5317            mInstrumentation = new Instrumentation();
5318        }
5319
5320        if ((data.appInfo.flags&ApplicationInfo.FLAG_LARGE_HEAP) != 0) {
5321            dalvik.system.VMRuntime.getRuntime().clearGrowthLimit();
5322        } else {
5323            // Small heap, clamp to the current growth limit and let the heap release
5324            // pages after the growth limit to the non growth limit capacity. b/18387825
5325            dalvik.system.VMRuntime.getRuntime().clampGrowthLimit();
5326        }
5327
5328        // Allow disk access during application and provider setup. This could
5329        // block processing ordered broadcasts, but later processing would
5330        // probably end up doing the same disk access.
5331        final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskWrites();
5332        try {
5333            // If the app is being launched for full backup or restore, bring it up in
5334            // a restricted environment with the base application class.
5335            Application app = data.info.makeApplication(data.restrictedBackupMode, null);
5336            mInitialApplication = app;
5337
5338            // don't bring up providers in restricted mode; they may depend on the
5339            // app's custom Application class
5340            if (!data.restrictedBackupMode) {
5341                if (!ArrayUtils.isEmpty(data.providers)) {
5342                    installContentProviders(app, data.providers);
5343                    // For process that contains content providers, we want to
5344                    // ensure that the JIT is enabled "at some point".
5345                    mH.sendEmptyMessageDelayed(H.ENABLE_JIT, 10*1000);
5346                }
5347            }
5348
5349            // Do this after providers, since instrumentation tests generally start their
5350            // test thread at this point, and we don't want that racing.
5351            try {
5352                mInstrumentation.onCreate(data.instrumentationArgs);
5353            }
5354            catch (Exception e) {
5355                throw new RuntimeException(
5356                    "Exception thrown in onCreate() of "
5357                    + data.instrumentationName + ": " + e.toString(), e);
5358            }
5359
5360            try {
5361                mInstrumentation.callApplicationOnCreate(app);
5362            } catch (Exception e) {
5363                if (!mInstrumentation.onException(app, e)) {
5364                    throw new RuntimeException(
5365                        "Unable to create application " + app.getClass().getName()
5366                        + ": " + e.toString(), e);
5367                }
5368            }
5369        } finally {
5370            StrictMode.setThreadPolicy(savedPolicy);
5371        }
5372    }
5373
5374    /*package*/ final void finishInstrumentation(int resultCode, Bundle results) {
5375        IActivityManager am = ActivityManagerNative.getDefault();
5376        if (mProfiler.profileFile != null && mProfiler.handlingProfiling
5377                && mProfiler.profileFd == null) {
5378            Debug.stopMethodTracing();
5379        }
5380        //Slog.i(TAG, "am: " + ActivityManagerNative.getDefault()
5381        //      + ", app thr: " + mAppThread);
5382        try {
5383            am.finishInstrumentation(mAppThread, resultCode, results);
5384        } catch (RemoteException ex) {
5385            throw ex.rethrowFromSystemServer();
5386        }
5387    }
5388
5389    private void installContentProviders(
5390            Context context, List<ProviderInfo> providers) {
5391        final ArrayList<IActivityManager.ContentProviderHolder> results =
5392            new ArrayList<IActivityManager.ContentProviderHolder>();
5393
5394        for (ProviderInfo cpi : providers) {
5395            if (DEBUG_PROVIDER) {
5396                StringBuilder buf = new StringBuilder(128);
5397                buf.append("Pub ");
5398                buf.append(cpi.authority);
5399                buf.append(": ");
5400                buf.append(cpi.name);
5401                Log.i(TAG, buf.toString());
5402            }
5403            IActivityManager.ContentProviderHolder cph = installProvider(context, null, cpi,
5404                    false /*noisy*/, true /*noReleaseNeeded*/, true /*stable*/);
5405            if (cph != null) {
5406                cph.noReleaseNeeded = true;
5407                results.add(cph);
5408            }
5409        }
5410
5411        try {
5412            ActivityManagerNative.getDefault().publishContentProviders(
5413                getApplicationThread(), results);
5414        } catch (RemoteException ex) {
5415            throw ex.rethrowFromSystemServer();
5416        }
5417    }
5418
5419    public final IContentProvider acquireProvider(
5420            Context c, String auth, int userId, boolean stable) {
5421        final IContentProvider provider = acquireExistingProvider(c, auth, userId, stable);
5422        if (provider != null) {
5423            return provider;
5424        }
5425
5426        // There is a possible race here.  Another thread may try to acquire
5427        // the same provider at the same time.  When this happens, we want to ensure
5428        // that the first one wins.
5429        // Note that we cannot hold the lock while acquiring and installing the
5430        // provider since it might take a long time to run and it could also potentially
5431        // be re-entrant in the case where the provider is in the same process.
5432        IActivityManager.ContentProviderHolder holder = null;
5433        try {
5434            holder = ActivityManagerNative.getDefault().getContentProvider(
5435                    getApplicationThread(), auth, userId, stable);
5436        } catch (RemoteException ex) {
5437            throw ex.rethrowFromSystemServer();
5438        }
5439        if (holder == null) {
5440            Slog.e(TAG, "Failed to find provider info for " + auth);
5441            return null;
5442        }
5443
5444        // Install provider will increment the reference count for us, and break
5445        // any ties in the race.
5446        holder = installProvider(c, holder, holder.info,
5447                true /*noisy*/, holder.noReleaseNeeded, stable);
5448        return holder.provider;
5449    }
5450
5451    private final void incProviderRefLocked(ProviderRefCount prc, boolean stable) {
5452        if (stable) {
5453            prc.stableCount += 1;
5454            if (prc.stableCount == 1) {
5455                // We are acquiring a new stable reference on the provider.
5456                int unstableDelta;
5457                if (prc.removePending) {
5458                    // We have a pending remove operation, which is holding the
5459                    // last unstable reference.  At this point we are converting
5460                    // that unstable reference to our new stable reference.
5461                    unstableDelta = -1;
5462                    // Cancel the removal of the provider.
5463                    if (DEBUG_PROVIDER) {
5464                        Slog.v(TAG, "incProviderRef: stable "
5465                                + "snatched provider from the jaws of death");
5466                    }
5467                    prc.removePending = false;
5468                    // There is a race! It fails to remove the message, which
5469                    // will be handled in completeRemoveProvider().
5470                    mH.removeMessages(H.REMOVE_PROVIDER, prc);
5471                } else {
5472                    unstableDelta = 0;
5473                }
5474                try {
5475                    if (DEBUG_PROVIDER) {
5476                        Slog.v(TAG, "incProviderRef Now stable - "
5477                                + prc.holder.info.name + ": unstableDelta="
5478                                + unstableDelta);
5479                    }
5480                    ActivityManagerNative.getDefault().refContentProvider(
5481                            prc.holder.connection, 1, unstableDelta);
5482                } catch (RemoteException e) {
5483                    //do nothing content provider object is dead any way
5484                }
5485            }
5486        } else {
5487            prc.unstableCount += 1;
5488            if (prc.unstableCount == 1) {
5489                // We are acquiring a new unstable reference on the provider.
5490                if (prc.removePending) {
5491                    // Oh look, we actually have a remove pending for the
5492                    // provider, which is still holding the last unstable
5493                    // reference.  We just need to cancel that to take new
5494                    // ownership of the reference.
5495                    if (DEBUG_PROVIDER) {
5496                        Slog.v(TAG, "incProviderRef: unstable "
5497                                + "snatched provider from the jaws of death");
5498                    }
5499                    prc.removePending = false;
5500                    mH.removeMessages(H.REMOVE_PROVIDER, prc);
5501                } else {
5502                    // First unstable ref, increment our count in the
5503                    // activity manager.
5504                    try {
5505                        if (DEBUG_PROVIDER) {
5506                            Slog.v(TAG, "incProviderRef: Now unstable - "
5507                                    + prc.holder.info.name);
5508                        }
5509                        ActivityManagerNative.getDefault().refContentProvider(
5510                                prc.holder.connection, 0, 1);
5511                    } catch (RemoteException e) {
5512                        //do nothing content provider object is dead any way
5513                    }
5514                }
5515            }
5516        }
5517    }
5518
5519    public final IContentProvider acquireExistingProvider(
5520            Context c, String auth, int userId, boolean stable) {
5521        synchronized (mProviderMap) {
5522            final ProviderKey key = new ProviderKey(auth, userId);
5523            final ProviderClientRecord pr = mProviderMap.get(key);
5524            if (pr == null) {
5525                return null;
5526            }
5527
5528            IContentProvider provider = pr.mProvider;
5529            IBinder jBinder = provider.asBinder();
5530            if (!jBinder.isBinderAlive()) {
5531                // The hosting process of the provider has died; we can't
5532                // use this one.
5533                Log.i(TAG, "Acquiring provider " + auth + " for user " + userId
5534                        + ": existing object's process dead");
5535                handleUnstableProviderDiedLocked(jBinder, true);
5536                return null;
5537            }
5538
5539            // Only increment the ref count if we have one.  If we don't then the
5540            // provider is not reference counted and never needs to be released.
5541            ProviderRefCount prc = mProviderRefCountMap.get(jBinder);
5542            if (prc != null) {
5543                incProviderRefLocked(prc, stable);
5544            }
5545            return provider;
5546        }
5547    }
5548
5549    public final boolean releaseProvider(IContentProvider provider, boolean stable) {
5550        if (provider == null) {
5551            return false;
5552        }
5553
5554        IBinder jBinder = provider.asBinder();
5555        synchronized (mProviderMap) {
5556            ProviderRefCount prc = mProviderRefCountMap.get(jBinder);
5557            if (prc == null) {
5558                // The provider has no ref count, no release is needed.
5559                return false;
5560            }
5561
5562            boolean lastRef = false;
5563            if (stable) {
5564                if (prc.stableCount == 0) {
5565                    if (DEBUG_PROVIDER) Slog.v(TAG,
5566                            "releaseProvider: stable ref count already 0, how?");
5567                    return false;
5568                }
5569                prc.stableCount -= 1;
5570                if (prc.stableCount == 0) {
5571                    // What we do at this point depends on whether there are
5572                    // any unstable refs left: if there are, we just tell the
5573                    // activity manager to decrement its stable count; if there
5574                    // aren't, we need to enqueue this provider to be removed,
5575                    // and convert to holding a single unstable ref while
5576                    // doing so.
5577                    lastRef = prc.unstableCount == 0;
5578                    try {
5579                        if (DEBUG_PROVIDER) {
5580                            Slog.v(TAG, "releaseProvider: No longer stable w/lastRef="
5581                                    + lastRef + " - " + prc.holder.info.name);
5582                        }
5583                        ActivityManagerNative.getDefault().refContentProvider(
5584                                prc.holder.connection, -1, lastRef ? 1 : 0);
5585                    } catch (RemoteException e) {
5586                        //do nothing content provider object is dead any way
5587                    }
5588                }
5589            } else {
5590                if (prc.unstableCount == 0) {
5591                    if (DEBUG_PROVIDER) Slog.v(TAG,
5592                            "releaseProvider: unstable ref count already 0, how?");
5593                    return false;
5594                }
5595                prc.unstableCount -= 1;
5596                if (prc.unstableCount == 0) {
5597                    // If this is the last reference, we need to enqueue
5598                    // this provider to be removed instead of telling the
5599                    // activity manager to remove it at this point.
5600                    lastRef = prc.stableCount == 0;
5601                    if (!lastRef) {
5602                        try {
5603                            if (DEBUG_PROVIDER) {
5604                                Slog.v(TAG, "releaseProvider: No longer unstable - "
5605                                        + prc.holder.info.name);
5606                            }
5607                            ActivityManagerNative.getDefault().refContentProvider(
5608                                    prc.holder.connection, 0, -1);
5609                        } catch (RemoteException e) {
5610                            //do nothing content provider object is dead any way
5611                        }
5612                    }
5613                }
5614            }
5615
5616            if (lastRef) {
5617                if (!prc.removePending) {
5618                    // Schedule the actual remove asynchronously, since we don't know the context
5619                    // this will be called in.
5620                    // TODO: it would be nice to post a delayed message, so
5621                    // if we come back and need the same provider quickly
5622                    // we will still have it available.
5623                    if (DEBUG_PROVIDER) {
5624                        Slog.v(TAG, "releaseProvider: Enqueueing pending removal - "
5625                                + prc.holder.info.name);
5626                    }
5627                    prc.removePending = true;
5628                    Message msg = mH.obtainMessage(H.REMOVE_PROVIDER, prc);
5629                    mH.sendMessage(msg);
5630                } else {
5631                    Slog.w(TAG, "Duplicate remove pending of provider " + prc.holder.info.name);
5632                }
5633            }
5634            return true;
5635        }
5636    }
5637
5638    final void completeRemoveProvider(ProviderRefCount prc) {
5639        synchronized (mProviderMap) {
5640            if (!prc.removePending) {
5641                // There was a race!  Some other client managed to acquire
5642                // the provider before the removal was completed.
5643                // Abort the removal.  We will do it later.
5644                if (DEBUG_PROVIDER) Slog.v(TAG, "completeRemoveProvider: lost the race, "
5645                        + "provider still in use");
5646                return;
5647            }
5648
5649            // More complicated race!! Some client managed to acquire the
5650            // provider and release it before the removal was completed.
5651            // Continue the removal, and abort the next remove message.
5652            prc.removePending = false;
5653
5654            final IBinder jBinder = prc.holder.provider.asBinder();
5655            ProviderRefCount existingPrc = mProviderRefCountMap.get(jBinder);
5656            if (existingPrc == prc) {
5657                mProviderRefCountMap.remove(jBinder);
5658            }
5659
5660            for (int i=mProviderMap.size()-1; i>=0; i--) {
5661                ProviderClientRecord pr = mProviderMap.valueAt(i);
5662                IBinder myBinder = pr.mProvider.asBinder();
5663                if (myBinder == jBinder) {
5664                    mProviderMap.removeAt(i);
5665                }
5666            }
5667        }
5668
5669        try {
5670            if (DEBUG_PROVIDER) {
5671                Slog.v(TAG, "removeProvider: Invoking ActivityManagerNative."
5672                        + "removeContentProvider(" + prc.holder.info.name + ")");
5673            }
5674            ActivityManagerNative.getDefault().removeContentProvider(
5675                    prc.holder.connection, false);
5676        } catch (RemoteException e) {
5677            //do nothing content provider object is dead any way
5678        }
5679    }
5680
5681    final void handleUnstableProviderDied(IBinder provider, boolean fromClient) {
5682        synchronized (mProviderMap) {
5683            handleUnstableProviderDiedLocked(provider, fromClient);
5684        }
5685    }
5686
5687    final void handleUnstableProviderDiedLocked(IBinder provider, boolean fromClient) {
5688        ProviderRefCount prc = mProviderRefCountMap.get(provider);
5689        if (prc != null) {
5690            if (DEBUG_PROVIDER) Slog.v(TAG, "Cleaning up dead provider "
5691                    + provider + " " + prc.holder.info.name);
5692            mProviderRefCountMap.remove(provider);
5693            for (int i=mProviderMap.size()-1; i>=0; i--) {
5694                ProviderClientRecord pr = mProviderMap.valueAt(i);
5695                if (pr != null && pr.mProvider.asBinder() == provider) {
5696                    Slog.i(TAG, "Removing dead content provider:" + pr.mProvider.toString());
5697                    mProviderMap.removeAt(i);
5698                }
5699            }
5700
5701            if (fromClient) {
5702                // We found out about this due to execution in our client
5703                // code.  Tell the activity manager about it now, to ensure
5704                // that the next time we go to do anything with the provider
5705                // it knows it is dead (so we don't race with its death
5706                // notification).
5707                try {
5708                    ActivityManagerNative.getDefault().unstableProviderDied(
5709                            prc.holder.connection);
5710                } catch (RemoteException e) {
5711                    //do nothing content provider object is dead any way
5712                }
5713            }
5714        }
5715    }
5716
5717    final void appNotRespondingViaProvider(IBinder provider) {
5718        synchronized (mProviderMap) {
5719            ProviderRefCount prc = mProviderRefCountMap.get(provider);
5720            if (prc != null) {
5721                try {
5722                    ActivityManagerNative.getDefault()
5723                            .appNotRespondingViaProvider(prc.holder.connection);
5724                } catch (RemoteException e) {
5725                    throw e.rethrowFromSystemServer();
5726                }
5727            }
5728        }
5729    }
5730
5731    private ProviderClientRecord installProviderAuthoritiesLocked(IContentProvider provider,
5732            ContentProvider localProvider, IActivityManager.ContentProviderHolder holder) {
5733        final String auths[] = holder.info.authority.split(";");
5734        final int userId = UserHandle.getUserId(holder.info.applicationInfo.uid);
5735
5736        final ProviderClientRecord pcr = new ProviderClientRecord(
5737                auths, provider, localProvider, holder);
5738        for (String auth : auths) {
5739            final ProviderKey key = new ProviderKey(auth, userId);
5740            final ProviderClientRecord existing = mProviderMap.get(key);
5741            if (existing != null) {
5742                Slog.w(TAG, "Content provider " + pcr.mHolder.info.name
5743                        + " already published as " + auth);
5744            } else {
5745                mProviderMap.put(key, pcr);
5746            }
5747        }
5748        return pcr;
5749    }
5750
5751    /**
5752     * Installs the provider.
5753     *
5754     * Providers that are local to the process or that come from the system server
5755     * may be installed permanently which is indicated by setting noReleaseNeeded to true.
5756     * Other remote providers are reference counted.  The initial reference count
5757     * for all reference counted providers is one.  Providers that are not reference
5758     * counted do not have a reference count (at all).
5759     *
5760     * This method detects when a provider has already been installed.  When this happens,
5761     * it increments the reference count of the existing provider (if appropriate)
5762     * and returns the existing provider.  This can happen due to concurrent
5763     * attempts to acquire the same provider.
5764     */
5765    private IActivityManager.ContentProviderHolder installProvider(Context context,
5766            IActivityManager.ContentProviderHolder holder, ProviderInfo info,
5767            boolean noisy, boolean noReleaseNeeded, boolean stable) {
5768        ContentProvider localProvider = null;
5769        IContentProvider provider;
5770        if (holder == null || holder.provider == null) {
5771            if (DEBUG_PROVIDER || noisy) {
5772                Slog.d(TAG, "Loading provider " + info.authority + ": "
5773                        + info.name);
5774            }
5775            Context c = null;
5776            ApplicationInfo ai = info.applicationInfo;
5777            if (context.getPackageName().equals(ai.packageName)) {
5778                c = context;
5779            } else if (mInitialApplication != null &&
5780                    mInitialApplication.getPackageName().equals(ai.packageName)) {
5781                c = mInitialApplication;
5782            } else {
5783                try {
5784                    c = context.createPackageContext(ai.packageName,
5785                            Context.CONTEXT_INCLUDE_CODE);
5786                } catch (PackageManager.NameNotFoundException e) {
5787                    // Ignore
5788                }
5789            }
5790            if (c == null) {
5791                Slog.w(TAG, "Unable to get context for package " +
5792                      ai.packageName +
5793                      " while loading content provider " +
5794                      info.name);
5795                return null;
5796            }
5797            try {
5798                final java.lang.ClassLoader cl = c.getClassLoader();
5799                localProvider = (ContentProvider)cl.
5800                    loadClass(info.name).newInstance();
5801                provider = localProvider.getIContentProvider();
5802                if (provider == null) {
5803                    Slog.e(TAG, "Failed to instantiate class " +
5804                          info.name + " from sourceDir " +
5805                          info.applicationInfo.sourceDir);
5806                    return null;
5807                }
5808                if (DEBUG_PROVIDER) Slog.v(
5809                    TAG, "Instantiating local provider " + info.name);
5810                // XXX Need to create the correct context for this provider.
5811                localProvider.attachInfo(c, info);
5812            } catch (java.lang.Exception e) {
5813                if (!mInstrumentation.onException(null, e)) {
5814                    throw new RuntimeException(
5815                            "Unable to get provider " + info.name
5816                            + ": " + e.toString(), e);
5817                }
5818                return null;
5819            }
5820        } else {
5821            provider = holder.provider;
5822            if (DEBUG_PROVIDER) Slog.v(TAG, "Installing external provider " + info.authority + ": "
5823                    + info.name);
5824        }
5825
5826        IActivityManager.ContentProviderHolder retHolder;
5827
5828        synchronized (mProviderMap) {
5829            if (DEBUG_PROVIDER) Slog.v(TAG, "Checking to add " + provider
5830                    + " / " + info.name);
5831            IBinder jBinder = provider.asBinder();
5832            if (localProvider != null) {
5833                ComponentName cname = new ComponentName(info.packageName, info.name);
5834                ProviderClientRecord pr = mLocalProvidersByName.get(cname);
5835                if (pr != null) {
5836                    if (DEBUG_PROVIDER) {
5837                        Slog.v(TAG, "installProvider: lost the race, "
5838                                + "using existing local provider");
5839                    }
5840                    provider = pr.mProvider;
5841                } else {
5842                    holder = new IActivityManager.ContentProviderHolder(info);
5843                    holder.provider = provider;
5844                    holder.noReleaseNeeded = true;
5845                    pr = installProviderAuthoritiesLocked(provider, localProvider, holder);
5846                    mLocalProviders.put(jBinder, pr);
5847                    mLocalProvidersByName.put(cname, pr);
5848                }
5849                retHolder = pr.mHolder;
5850            } else {
5851                ProviderRefCount prc = mProviderRefCountMap.get(jBinder);
5852                if (prc != null) {
5853                    if (DEBUG_PROVIDER) {
5854                        Slog.v(TAG, "installProvider: lost the race, updating ref count");
5855                    }
5856                    // We need to transfer our new reference to the existing
5857                    // ref count, releasing the old one...  but only if
5858                    // release is needed (that is, it is not running in the
5859                    // system process).
5860                    if (!noReleaseNeeded) {
5861                        incProviderRefLocked(prc, stable);
5862                        try {
5863                            ActivityManagerNative.getDefault().removeContentProvider(
5864                                    holder.connection, stable);
5865                        } catch (RemoteException e) {
5866                            //do nothing content provider object is dead any way
5867                        }
5868                    }
5869                } else {
5870                    ProviderClientRecord client = installProviderAuthoritiesLocked(
5871                            provider, localProvider, holder);
5872                    if (noReleaseNeeded) {
5873                        prc = new ProviderRefCount(holder, client, 1000, 1000);
5874                    } else {
5875                        prc = stable
5876                                ? new ProviderRefCount(holder, client, 1, 0)
5877                                : new ProviderRefCount(holder, client, 0, 1);
5878                    }
5879                    mProviderRefCountMap.put(jBinder, prc);
5880                }
5881                retHolder = prc.holder;
5882            }
5883        }
5884
5885        return retHolder;
5886    }
5887
5888    private void attach(boolean system) {
5889        sCurrentActivityThread = this;
5890        mSystemThread = system;
5891        if (!system) {
5892            ViewRootImpl.addFirstDrawHandler(new Runnable() {
5893                @Override
5894                public void run() {
5895                    ensureJitEnabled();
5896                }
5897            });
5898            android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",
5899                                                    UserHandle.myUserId());
5900            RuntimeInit.setApplicationObject(mAppThread.asBinder());
5901            final IActivityManager mgr = ActivityManagerNative.getDefault();
5902            try {
5903                mgr.attachApplication(mAppThread);
5904            } catch (RemoteException ex) {
5905                throw ex.rethrowFromSystemServer();
5906            }
5907            // Watch for getting close to heap limit.
5908            BinderInternal.addGcWatcher(new Runnable() {
5909                @Override public void run() {
5910                    if (!mSomeActivitiesChanged) {
5911                        return;
5912                    }
5913                    Runtime runtime = Runtime.getRuntime();
5914                    long dalvikMax = runtime.maxMemory();
5915                    long dalvikUsed = runtime.totalMemory() - runtime.freeMemory();
5916                    if (dalvikUsed > ((3*dalvikMax)/4)) {
5917                        if (DEBUG_MEMORY_TRIM) Slog.d(TAG, "Dalvik max=" + (dalvikMax/1024)
5918                                + " total=" + (runtime.totalMemory()/1024)
5919                                + " used=" + (dalvikUsed/1024));
5920                        mSomeActivitiesChanged = false;
5921                        try {
5922                            mgr.releaseSomeActivities(mAppThread);
5923                        } catch (RemoteException e) {
5924                            throw e.rethrowFromSystemServer();
5925                        }
5926                    }
5927                }
5928            });
5929        } else {
5930            // Don't set application object here -- if the system crashes,
5931            // we can't display an alert, we just want to die die die.
5932            android.ddm.DdmHandleAppName.setAppName("system_process",
5933                    UserHandle.myUserId());
5934            try {
5935                mInstrumentation = new Instrumentation();
5936                ContextImpl context = ContextImpl.createAppContext(
5937                        this, getSystemContext().mPackageInfo);
5938                mInitialApplication = context.mPackageInfo.makeApplication(true, null);
5939                mInitialApplication.onCreate();
5940            } catch (Exception e) {
5941                throw new RuntimeException(
5942                        "Unable to instantiate Application():" + e.toString(), e);
5943            }
5944        }
5945
5946        // add dropbox logging to libcore
5947        DropBox.setReporter(new DropBoxReporter());
5948
5949        ViewRootImpl.addConfigCallback(new ComponentCallbacks2() {
5950            @Override
5951            public void onConfigurationChanged(Configuration newConfig) {
5952                synchronized (mResourcesManager) {
5953                    // We need to apply this change to the resources
5954                    // immediately, because upon returning the view
5955                    // hierarchy will be informed about it.
5956                    if (mResourcesManager.applyConfigurationToResourcesLocked(newConfig, null)) {
5957                        // This actually changed the resources!  Tell
5958                        // everyone about it.
5959                        if (mPendingConfiguration == null ||
5960                                mPendingConfiguration.isOtherSeqNewer(newConfig)) {
5961                            mPendingConfiguration = newConfig;
5962
5963                            sendMessage(H.CONFIGURATION_CHANGED, newConfig);
5964                        }
5965                    }
5966                }
5967            }
5968            @Override
5969            public void onLowMemory() {
5970            }
5971            @Override
5972            public void onTrimMemory(int level) {
5973            }
5974        });
5975    }
5976
5977    public static ActivityThread systemMain() {
5978        // The system process on low-memory devices do not get to use hardware
5979        // accelerated drawing, since this can add too much overhead to the
5980        // process.
5981        if (!ActivityManager.isHighEndGfx()) {
5982            ThreadedRenderer.disable(true);
5983        } else {
5984            ThreadedRenderer.enableForegroundTrimming();
5985        }
5986        ActivityThread thread = new ActivityThread();
5987        thread.attach(true);
5988        return thread;
5989    }
5990
5991    public final void installSystemProviders(List<ProviderInfo> providers) {
5992        if (providers != null) {
5993            installContentProviders(mInitialApplication, providers);
5994        }
5995    }
5996
5997    public int getIntCoreSetting(String key, int defaultValue) {
5998        synchronized (mResourcesManager) {
5999            if (mCoreSettings != null) {
6000                return mCoreSettings.getInt(key, defaultValue);
6001            }
6002            return defaultValue;
6003        }
6004    }
6005
6006    private static class EventLoggingReporter implements EventLogger.Reporter {
6007        @Override
6008        public void report (int code, Object... list) {
6009            EventLog.writeEvent(code, list);
6010        }
6011    }
6012
6013    private class DropBoxReporter implements DropBox.Reporter {
6014
6015        private DropBoxManager dropBox;
6016
6017        public DropBoxReporter() {}
6018
6019        @Override
6020        public void addData(String tag, byte[] data, int flags) {
6021            ensureInitialized();
6022            dropBox.addData(tag, data, flags);
6023        }
6024
6025        @Override
6026        public void addText(String tag, String data) {
6027            ensureInitialized();
6028            dropBox.addText(tag, data);
6029        }
6030
6031        private synchronized void ensureInitialized() {
6032            if (dropBox == null) {
6033                dropBox = (DropBoxManager) getSystemContext().getSystemService(Context.DROPBOX_SERVICE);
6034            }
6035        }
6036    }
6037
6038    public static void main(String[] args) {
6039        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");
6040        SamplingProfilerIntegration.start();
6041
6042        // CloseGuard defaults to true and can be quite spammy.  We
6043        // disable it here, but selectively enable it later (via
6044        // StrictMode) on debug builds, but using DropBox, not logs.
6045        CloseGuard.setEnabled(false);
6046
6047        Environment.initForCurrentUser();
6048
6049        // Set the reporter for event logging in libcore
6050        EventLogger.setReporter(new EventLoggingReporter());
6051
6052        AndroidKeyStoreProvider.install();
6053
6054        // Make sure TrustedCertificateStore looks in the right place for CA certificates
6055        final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
6056        TrustedCertificateStore.setDefaultUserDirectory(configDir);
6057
6058        Process.setArgV0("<pre-initialized>");
6059
6060        Looper.prepareMainLooper();
6061
6062        ActivityThread thread = new ActivityThread();
6063        thread.attach(false);
6064
6065        if (sMainThreadHandler == null) {
6066            sMainThreadHandler = thread.getHandler();
6067        }
6068
6069        if (false) {
6070            Looper.myLooper().setMessageLogging(new
6071                    LogPrinter(Log.DEBUG, "ActivityThread"));
6072        }
6073
6074        // End of event ActivityThreadMain.
6075        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6076        Looper.loop();
6077
6078        throw new RuntimeException("Main thread loop unexpectedly exited");
6079    }
6080}
6081