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