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