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