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