ActivityManagerService.java revision c7b31e3c3cd71129557d4bf9e3fbcebb9235aba5
1/*
2 * Copyright (C) 2006-2008 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 com.android.server.am;
18
19import com.android.internal.os.BatteryStatsImpl;
20import com.android.internal.os.RuntimeInit;
21import com.android.server.IntentResolver;
22import com.android.server.ProcessMap;
23import com.android.server.ProcessStats;
24import com.android.server.SystemServer;
25import com.android.server.Watchdog;
26import com.android.server.WindowManagerService;
27
28import android.app.Activity;
29import android.app.ActivityManager;
30import android.app.ActivityManagerNative;
31import android.app.ActivityThread;
32import android.app.AlertDialog;
33import android.app.ApplicationErrorReport;
34import android.app.Dialog;
35import android.app.IActivityWatcher;
36import android.app.IApplicationThread;
37import android.app.IInstrumentationWatcher;
38import android.app.IIntentReceiver;
39import android.app.IIntentSender;
40import android.app.IServiceConnection;
41import android.app.IThumbnailReceiver;
42import android.app.Instrumentation;
43import android.app.PendingIntent;
44import android.app.ResultInfo;
45import android.backup.IBackupManager;
46import android.content.ActivityNotFoundException;
47import android.content.ComponentName;
48import android.content.ContentResolver;
49import android.content.Context;
50import android.content.Intent;
51import android.content.IntentFilter;
52import android.content.pm.ActivityInfo;
53import android.content.pm.ApplicationInfo;
54import android.content.pm.ConfigurationInfo;
55import android.content.pm.IPackageDataObserver;
56import android.content.pm.IPackageManager;
57import android.content.pm.InstrumentationInfo;
58import android.content.pm.PackageManager;
59import android.content.pm.ProviderInfo;
60import android.content.pm.ResolveInfo;
61import android.content.pm.ServiceInfo;
62import android.content.res.Configuration;
63import android.graphics.Bitmap;
64import android.net.Uri;
65import android.os.BatteryStats;
66import android.os.Binder;
67import android.os.Bundle;
68import android.os.Environment;
69import android.os.FileUtils;
70import android.os.Handler;
71import android.os.IBinder;
72import android.os.IPermissionController;
73import android.os.Looper;
74import android.os.Message;
75import android.os.Parcel;
76import android.os.ParcelFileDescriptor;
77import android.os.PowerManager;
78import android.os.Process;
79import android.os.RemoteException;
80import android.os.ServiceManager;
81import android.os.SystemClock;
82import android.os.SystemProperties;
83import android.provider.Checkin;
84import android.provider.Settings;
85import android.server.data.CrashData;
86import android.server.data.StackTraceElementData;
87import android.server.data.ThrowableData;
88import android.text.TextUtils;
89import android.util.Config;
90import android.util.EventLog;
91import android.util.Log;
92import android.util.LogPrinter;
93import android.util.PrintWriterPrinter;
94import android.util.SparseArray;
95import android.view.Gravity;
96import android.view.LayoutInflater;
97import android.view.View;
98import android.view.WindowManager;
99import android.view.WindowManagerPolicy;
100
101import dalvik.system.Zygote;
102
103import java.io.ByteArrayInputStream;
104import java.io.DataInputStream;
105import java.io.File;
106import java.io.FileDescriptor;
107import java.io.FileInputStream;
108import java.io.FileNotFoundException;
109import java.io.IOException;
110import java.io.PrintWriter;
111import java.lang.IllegalStateException;
112import java.lang.ref.WeakReference;
113import java.util.ArrayList;
114import java.util.HashMap;
115import java.util.HashSet;
116import java.util.Iterator;
117import java.util.List;
118import java.util.Locale;
119import java.util.Map;
120
121public final class ActivityManagerService extends ActivityManagerNative implements Watchdog.Monitor {
122    static final String TAG = "ActivityManager";
123    static final boolean DEBUG = false;
124    static final boolean localLOGV = DEBUG ? Config.LOGD : Config.LOGV;
125    static final boolean DEBUG_SWITCH = localLOGV || false;
126    static final boolean DEBUG_TASKS = localLOGV || false;
127    static final boolean DEBUG_PAUSE = localLOGV || false;
128    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
129    static final boolean DEBUG_TRANSITION = localLOGV || false;
130    static final boolean DEBUG_BROADCAST = localLOGV || false;
131    static final boolean DEBUG_SERVICE = localLOGV || false;
132    static final boolean DEBUG_VISBILITY = localLOGV || false;
133    static final boolean DEBUG_PROCESSES = localLOGV || false;
134    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
135    static final boolean DEBUG_RESULTS = localLOGV || false;
136    static final boolean DEBUG_BACKUP = localLOGV || true;
137    static final boolean VALIDATE_TOKENS = false;
138    static final boolean SHOW_ACTIVITY_START_TIME = true;
139
140    // Control over CPU and battery monitoring.
141    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
142    static final boolean MONITOR_CPU_USAGE = true;
143    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
144    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
145    static final boolean MONITOR_THREAD_CPU_USAGE = false;
146
147    // Event log tags
148    static final int LOG_CONFIGURATION_CHANGED = 2719;
149    static final int LOG_CPU = 2721;
150    static final int LOG_AM_FINISH_ACTIVITY = 30001;
151    static final int LOG_TASK_TO_FRONT = 30002;
152    static final int LOG_AM_NEW_INTENT = 30003;
153    static final int LOG_AM_CREATE_TASK = 30004;
154    static final int LOG_AM_CREATE_ACTIVITY = 30005;
155    static final int LOG_AM_RESTART_ACTIVITY = 30006;
156    static final int LOG_AM_RESUME_ACTIVITY = 30007;
157    static final int LOG_ANR = 30008;
158    static final int LOG_ACTIVITY_LAUNCH_TIME = 30009;
159    static final int LOG_AM_PROCESS_BOUND = 30010;
160    static final int LOG_AM_PROCESS_DIED = 30011;
161    static final int LOG_AM_FAILED_TO_PAUSE_ACTIVITY = 30012;
162    static final int LOG_AM_PAUSE_ACTIVITY = 30013;
163    static final int LOG_AM_PROCESS_START = 30014;
164    static final int LOG_AM_PROCESS_BAD = 30015;
165    static final int LOG_AM_PROCESS_GOOD = 30016;
166    static final int LOG_AM_LOW_MEMORY = 30017;
167    static final int LOG_AM_DESTROY_ACTIVITY = 30018;
168    static final int LOG_AM_RELAUNCH_RESUME_ACTIVITY = 30019;
169    static final int LOG_AM_RELAUNCH_ACTIVITY = 30020;
170    static final int LOG_AM_KILL_FOR_MEMORY = 30023;
171    static final int LOG_AM_BROADCAST_DISCARD_FILTER = 30024;
172    static final int LOG_AM_BROADCAST_DISCARD_APP = 30025;
173    static final int LOG_AM_CREATE_SERVICE = 30030;
174    static final int LOG_AM_DESTROY_SERVICE = 30031;
175    static final int LOG_AM_PROCESS_CRASHED_TOO_MUCH = 30032;
176    static final int LOG_AM_DROP_PROCESS = 30033;
177    static final int LOG_AM_SERVICE_CRASHED_TOO_MUCH = 30034;
178    static final int LOG_AM_SCHEDULE_SERVICE_RESTART = 30035;
179    static final int LOG_AM_PROVIDER_LOST_PROCESS = 30036;
180
181    static final int LOG_BOOT_PROGRESS_AMS_READY = 3040;
182    static final int LOG_BOOT_PROGRESS_ENABLE_SCREEN = 3050;
183
184    // The flags that are set for all calls we make to the package manager.
185    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES
186            | PackageManager.GET_SUPPORTS_DENSITIES | PackageManager.GET_EXPANDABLE;
187
188    private static final String SYSTEM_SECURE = "ro.secure";
189
190    // This is the maximum number of application processes we would like
191    // to have running.  Due to the asynchronous nature of things, we can
192    // temporarily go beyond this limit.
193    static final int MAX_PROCESSES = 2;
194
195    // Set to false to leave processes running indefinitely, relying on
196    // the kernel killing them as resources are required.
197    static final boolean ENFORCE_PROCESS_LIMIT = false;
198
199    // This is the maximum number of activities that we would like to have
200    // running at a given time.
201    static final int MAX_ACTIVITIES = 20;
202
203    // Maximum number of recent tasks that we can remember.
204    static final int MAX_RECENT_TASKS = 20;
205
206    // Amount of time after a call to stopAppSwitches() during which we will
207    // prevent further untrusted switches from happening.
208    static final long APP_SWITCH_DELAY_TIME = 5*1000;
209
210    // How long until we reset a task when the user returns to it.  Currently
211    // 30 minutes.
212    static final long ACTIVITY_INACTIVE_RESET_TIME = 1000*60*30;
213
214    // Set to true to disable the icon that is shown while a new activity
215    // is being started.
216    static final boolean SHOW_APP_STARTING_ICON = true;
217
218    // How long we wait until giving up on the last activity to pause.  This
219    // is short because it directly impacts the responsiveness of starting the
220    // next activity.
221    static final int PAUSE_TIMEOUT = 500;
222
223    /**
224     * How long we can hold the launch wake lock before giving up.
225     */
226    static final int LAUNCH_TIMEOUT = 10*1000;
227
228    // How long we wait for a launched process to attach to the activity manager
229    // before we decide it's never going to come up for real.
230    static final int PROC_START_TIMEOUT = 10*1000;
231
232    // How long we wait until giving up on the last activity telling us it
233    // is idle.
234    static final int IDLE_TIMEOUT = 10*1000;
235
236    // How long to wait after going idle before forcing apps to GC.
237    static final int GC_TIMEOUT = 5*1000;
238
239    // How long we wait until giving up on an activity telling us it has
240    // finished destroying itself.
241    static final int DESTROY_TIMEOUT = 10*1000;
242
243    // How long we allow a receiver to run before giving up on it.
244    static final int BROADCAST_TIMEOUT = 10*1000;
245
246    // How long we wait for a service to finish executing.
247    static final int SERVICE_TIMEOUT = 20*1000;
248
249    // How long a service needs to be running until restarting its process
250    // is no longer considered to be a relaunch of the service.
251    static final int SERVICE_RESTART_DURATION = 5*1000;
252
253    // Maximum amount of time for there to be no activity on a service before
254    // we consider it non-essential and allow its process to go on the
255    // LRU background list.
256    static final int MAX_SERVICE_INACTIVITY = 10*60*1000;
257
258    // How long we wait until we timeout on key dispatching.
259    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
260
261    // The minimum time we allow between crashes, for us to consider this
262    // application to be bad and stop and its services and reject broadcasts.
263    static final int MIN_CRASH_INTERVAL = 60*1000;
264
265    // How long we wait until we timeout on key dispatching during instrumentation.
266    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
267
268    // OOM adjustments for processes in various states:
269
270    // This is a process without anything currently running in it.  Definitely
271    // the first to go! Value set in system/rootdir/init.rc on startup.
272    // This value is initalized in the constructor, careful when refering to
273    // this static variable externally.
274    static int EMPTY_APP_ADJ;
275
276    // This is a process with a content provider that does not have any clients
277    // attached to it.  If it did have any clients, its adjustment would be the
278    // one for the highest-priority of those processes.
279    static int CONTENT_PROVIDER_ADJ;
280
281    // This is a process only hosting activities that are not visible,
282    // so it can be killed without any disruption. Value set in
283    // system/rootdir/init.rc on startup.
284    final int HIDDEN_APP_MAX_ADJ;
285    static int HIDDEN_APP_MIN_ADJ;
286
287    // This is a process holding the home application -- we want to try
288    // avoiding killing it, even if it would normally be in the background,
289    // because the user interacts with it so much.
290    final int HOME_APP_ADJ;
291
292    // This is a process currently hosting a backup operation.  Killing it
293    // is not entirely fatal but is generally a bad idea.
294    final int BACKUP_APP_ADJ;
295
296    // This is a process holding a secondary server -- killing it will not
297    // have much of an impact as far as the user is concerned. Value set in
298    // system/rootdir/init.rc on startup.
299    final int SECONDARY_SERVER_ADJ;
300
301    // This is a process only hosting activities that are visible to the
302    // user, so we'd prefer they don't disappear. Value set in
303    // system/rootdir/init.rc on startup.
304    final int VISIBLE_APP_ADJ;
305
306    // This is the process running the current foreground app.  We'd really
307    // rather not kill it! Value set in system/rootdir/init.rc on startup.
308    final int FOREGROUND_APP_ADJ;
309
310    // This is a process running a core server, such as telephony.  Definitely
311    // don't want to kill it, but doing so is not completely fatal.
312    static final int CORE_SERVER_ADJ = -12;
313
314    // The system process runs at the default adjustment.
315    static final int SYSTEM_ADJ = -16;
316
317    // Memory pages are 4K.
318    static final int PAGE_SIZE = 4*1024;
319
320    // Corresponding memory levels for above adjustments.
321    final int EMPTY_APP_MEM;
322    final int HIDDEN_APP_MEM;
323    final int HOME_APP_MEM;
324    final int BACKUP_APP_MEM;
325    final int SECONDARY_SERVER_MEM;
326    final int VISIBLE_APP_MEM;
327    final int FOREGROUND_APP_MEM;
328
329    final int MY_PID;
330
331    static final String[] EMPTY_STRING_ARRAY = new String[0];
332
333    enum ActivityState {
334        INITIALIZING,
335        RESUMED,
336        PAUSING,
337        PAUSED,
338        STOPPING,
339        STOPPED,
340        FINISHING,
341        DESTROYING,
342        DESTROYED
343    }
344
345    /**
346     * The back history of all previous (and possibly still
347     * running) activities.  It contains HistoryRecord objects.
348     */
349    final ArrayList mHistory = new ArrayList();
350
351    /**
352     * Description of a request to start a new activity, which has been held
353     * due to app switches being disabled.
354     */
355    class PendingActivityLaunch {
356        HistoryRecord r;
357        HistoryRecord sourceRecord;
358        Uri[] grantedUriPermissions;
359        int grantedMode;
360        boolean onlyIfNeeded;
361    }
362
363    final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
364            = new ArrayList<PendingActivityLaunch>();
365
366    /**
367     * List of all active broadcasts that are to be executed immediately
368     * (without waiting for another broadcast to finish).  Currently this only
369     * contains broadcasts to registered receivers, to avoid spinning up
370     * a bunch of processes to execute IntentReceiver components.
371     */
372    final ArrayList<BroadcastRecord> mParallelBroadcasts
373            = new ArrayList<BroadcastRecord>();
374
375    /**
376     * List of all active broadcasts that are to be executed one at a time.
377     * The object at the top of the list is the currently activity broadcasts;
378     * those after it are waiting for the top to finish..
379     */
380    final ArrayList<BroadcastRecord> mOrderedBroadcasts
381            = new ArrayList<BroadcastRecord>();
382
383    /**
384     * Set when we current have a BROADCAST_INTENT_MSG in flight.
385     */
386    boolean mBroadcastsScheduled = false;
387
388    /**
389     * Set to indicate whether to issue an onUserLeaving callback when a
390     * newly launched activity is being brought in front of us.
391     */
392    boolean mUserLeaving = false;
393
394    /**
395     * When we are in the process of pausing an activity, before starting the
396     * next one, this variable holds the activity that is currently being paused.
397     */
398    HistoryRecord mPausingActivity = null;
399
400    /**
401     * Current activity that is resumed, or null if there is none.
402     */
403    HistoryRecord mResumedActivity = null;
404
405    /**
406     * Activity we have told the window manager to have key focus.
407     */
408    HistoryRecord mFocusedActivity = null;
409
410    /**
411     * This is the last activity that we put into the paused state.  This is
412     * used to determine if we need to do an activity transition while sleeping,
413     * when we normally hold the top activity paused.
414     */
415    HistoryRecord mLastPausedActivity = null;
416
417    /**
418     * List of activities that are waiting for a new activity
419     * to become visible before completing whatever operation they are
420     * supposed to do.
421     */
422    final ArrayList mWaitingVisibleActivities = new ArrayList();
423
424    /**
425     * List of activities that are ready to be stopped, but waiting
426     * for the next activity to settle down before doing so.  It contains
427     * HistoryRecord objects.
428     */
429    final ArrayList<HistoryRecord> mStoppingActivities
430            = new ArrayList<HistoryRecord>();
431
432    /**
433     * List of intents that were used to start the most recent tasks.
434     */
435    final ArrayList<TaskRecord> mRecentTasks
436            = new ArrayList<TaskRecord>();
437
438    /**
439     * List of activities that are ready to be finished, but waiting
440     * for the previous activity to settle down before doing so.  It contains
441     * HistoryRecord objects.
442     */
443    final ArrayList mFinishingActivities = new ArrayList();
444
445    /**
446     * All of the applications we currently have running organized by name.
447     * The keys are strings of the application package name (as
448     * returned by the package manager), and the keys are ApplicationRecord
449     * objects.
450     */
451    final ProcessMap<ProcessRecord> mProcessNames
452            = new ProcessMap<ProcessRecord>();
453
454    /**
455     * The last time that various processes have crashed.
456     */
457    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
458
459    /**
460     * Set of applications that we consider to be bad, and will reject
461     * incoming broadcasts from (which the user has no control over).
462     * Processes are added to this set when they have crashed twice within
463     * a minimum amount of time; they are removed from it when they are
464     * later restarted (hopefully due to some user action).  The value is the
465     * time it was added to the list.
466     */
467    final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>();
468
469    /**
470     * All of the processes we currently have running organized by pid.
471     * The keys are the pid running the application.
472     *
473     * <p>NOTE: This object is protected by its own lock, NOT the global
474     * activity manager lock!
475     */
476    final SparseArray<ProcessRecord> mPidsSelfLocked
477            = new SparseArray<ProcessRecord>();
478
479    /**
480     * All of the processes that have been forced to be foreground.  The key
481     * is the pid of the caller who requested it (we hold a death
482     * link on it).
483     */
484    abstract class ForegroundToken implements IBinder.DeathRecipient {
485        int pid;
486        IBinder token;
487    }
488    final SparseArray<ForegroundToken> mForegroundProcesses
489            = new SparseArray<ForegroundToken>();
490
491    /**
492     * List of records for processes that someone had tried to start before the
493     * system was ready.  We don't start them at that point, but ensure they
494     * are started by the time booting is complete.
495     */
496    final ArrayList<ProcessRecord> mProcessesOnHold
497            = new ArrayList<ProcessRecord>();
498
499    /**
500     * List of records for processes that we have started and are waiting
501     * for them to call back.  This is really only needed when running in
502     * single processes mode, in which case we do not have a unique pid for
503     * each process.
504     */
505    final ArrayList<ProcessRecord> mStartingProcesses
506            = new ArrayList<ProcessRecord>();
507
508    /**
509     * List of persistent applications that are in the process
510     * of being started.
511     */
512    final ArrayList<ProcessRecord> mPersistentStartingProcesses
513            = new ArrayList<ProcessRecord>();
514
515    /**
516     * Processes that are being forcibly torn down.
517     */
518    final ArrayList<ProcessRecord> mRemovedProcesses
519            = new ArrayList<ProcessRecord>();
520
521    /**
522     * List of running applications, sorted by recent usage.
523     * The first entry in the list is the least recently used.
524     * It contains ApplicationRecord objects.  This list does NOT include
525     * any persistent application records (since we never want to exit them).
526     */
527    final ArrayList<ProcessRecord> mLRUProcesses
528            = new ArrayList<ProcessRecord>();
529
530    /**
531     * List of processes that should gc as soon as things are idle.
532     */
533    final ArrayList<ProcessRecord> mProcessesToGc
534            = new ArrayList<ProcessRecord>();
535
536    /**
537     * This is the process holding what we currently consider to be
538     * the "home" activity.
539     */
540    private ProcessRecord mHomeProcess;
541
542    /**
543     * List of running activities, sorted by recent usage.
544     * The first entry in the list is the least recently used.
545     * It contains HistoryRecord objects.
546     */
547    private final ArrayList mLRUActivities = new ArrayList();
548
549    /**
550     * Set of PendingResultRecord objects that are currently active.
551     */
552    final HashSet mPendingResultRecords = new HashSet();
553
554    /**
555     * Set of IntentSenderRecord objects that are currently active.
556     */
557    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
558            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
559
560    /**
561     * Intent broadcast that we have tried to start, but are
562     * waiting for its application's process to be created.  We only
563     * need one (instead of a list) because we always process broadcasts
564     * one at a time, so no others can be started while waiting for this
565     * one.
566     */
567    BroadcastRecord mPendingBroadcast = null;
568
569    /**
570     * Keeps track of all IIntentReceivers that have been registered for
571     * broadcasts.  Hash keys are the receiver IBinder, hash value is
572     * a ReceiverList.
573     */
574    final HashMap mRegisteredReceivers = new HashMap();
575
576    /**
577     * Resolver for broadcast intents to registered receivers.
578     * Holds BroadcastFilter (subclass of IntentFilter).
579     */
580    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
581            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
582        @Override
583        protected boolean allowFilterResult(
584                BroadcastFilter filter, List<BroadcastFilter> dest) {
585            IBinder target = filter.receiverList.receiver.asBinder();
586            for (int i=dest.size()-1; i>=0; i--) {
587                if (dest.get(i).receiverList.receiver.asBinder() == target) {
588                    return false;
589                }
590            }
591            return true;
592        }
593    };
594
595    /**
596     * State of all active sticky broadcasts.  Keys are the action of the
597     * sticky Intent, values are an ArrayList of all broadcasted intents with
598     * that action (which should usually be one).
599     */
600    final HashMap<String, ArrayList<Intent>> mStickyBroadcasts =
601            new HashMap<String, ArrayList<Intent>>();
602
603    /**
604     * All currently running services.
605     */
606    final HashMap<ComponentName, ServiceRecord> mServices =
607        new HashMap<ComponentName, ServiceRecord>();
608
609    /**
610     * All currently running services indexed by the Intent used to start them.
611     */
612    final HashMap<Intent.FilterComparison, ServiceRecord> mServicesByIntent =
613        new HashMap<Intent.FilterComparison, ServiceRecord>();
614
615    /**
616     * All currently bound service connections.  Keys are the IBinder of
617     * the client's IServiceConnection.
618     */
619    final HashMap<IBinder, ConnectionRecord> mServiceConnections
620            = new HashMap<IBinder, ConnectionRecord>();
621
622    /**
623     * List of services that we have been asked to start,
624     * but haven't yet been able to.  It is used to hold start requests
625     * while waiting for their corresponding application thread to get
626     * going.
627     */
628    final ArrayList<ServiceRecord> mPendingServices
629            = new ArrayList<ServiceRecord>();
630
631    /**
632     * List of services that are scheduled to restart following a crash.
633     */
634    final ArrayList<ServiceRecord> mRestartingServices
635            = new ArrayList<ServiceRecord>();
636
637    /**
638     * List of services that are in the process of being stopped.
639     */
640    final ArrayList<ServiceRecord> mStoppingServices
641            = new ArrayList<ServiceRecord>();
642
643    /**
644     * Backup/restore process management
645     */
646    String mBackupAppName = null;
647    BackupRecord mBackupTarget = null;
648
649    /**
650     * List of PendingThumbnailsRecord objects of clients who are still
651     * waiting to receive all of the thumbnails for a task.
652     */
653    final ArrayList mPendingThumbnails = new ArrayList();
654
655    /**
656     * List of HistoryRecord objects that have been finished and must
657     * still report back to a pending thumbnail receiver.
658     */
659    final ArrayList mCancelledThumbnails = new ArrayList();
660
661    /**
662     * All of the currently running global content providers.  Keys are a
663     * string containing the provider name and values are a
664     * ContentProviderRecord object containing the data about it.  Note
665     * that a single provider may be published under multiple names, so
666     * there may be multiple entries here for a single one in mProvidersByClass.
667     */
668    final HashMap mProvidersByName = new HashMap();
669
670    /**
671     * All of the currently running global content providers.  Keys are a
672     * string containing the provider's implementation class and values are a
673     * ContentProviderRecord object containing the data about it.
674     */
675    final HashMap mProvidersByClass = new HashMap();
676
677    /**
678     * List of content providers who have clients waiting for them.  The
679     * application is currently being launched and the provider will be
680     * removed from this list once it is published.
681     */
682    final ArrayList mLaunchingProviders = new ArrayList();
683
684    /**
685     * Global set of specific Uri permissions that have been granted.
686     */
687    final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions
688            = new SparseArray<HashMap<Uri, UriPermission>>();
689
690    /**
691     * Thread-local storage used to carry caller permissions over through
692     * indirect content-provider access.
693     * @see #ActivityManagerService.openContentUri()
694     */
695    private class Identity {
696        public int pid;
697        public int uid;
698
699        Identity(int _pid, int _uid) {
700            pid = _pid;
701            uid = _uid;
702        }
703    }
704    private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
705
706    /**
707     * All information we have collected about the runtime performance of
708     * any user id that can impact battery performance.
709     */
710    final BatteryStatsService mBatteryStatsService;
711
712    /**
713     * information about component usage
714     */
715    final UsageStatsService mUsageStatsService;
716
717    /**
718     * Current configuration information.  HistoryRecord objects are given
719     * a reference to this object to indicate which configuration they are
720     * currently running in, so this object must be kept immutable.
721     */
722    Configuration mConfiguration = new Configuration();
723
724    /**
725     * List of initialization arguments to pass to all processes when binding applications to them.
726     * For example, references to the commonly used services.
727     */
728    HashMap<String, IBinder> mAppBindArgs;
729
730    /**
731     * Temporary to avoid allocations.  Protected by main lock.
732     */
733    final StringBuilder mStringBuilder = new StringBuilder(256);
734
735    /**
736     * Used to control how we initialize the service.
737     */
738    boolean mStartRunning = false;
739    ComponentName mTopComponent;
740    String mTopAction;
741    String mTopData;
742    boolean mSystemReady = false;
743    boolean mBooting = false;
744
745    Context mContext;
746
747    int mFactoryTest;
748
749    /**
750     * The time at which we will allow normal application switches again,
751     * after a call to {@link #stopAppSwitches()}.
752     */
753    long mAppSwitchesAllowedTime;
754
755    /**
756     * This is set to true after the first switch after mAppSwitchesAllowedTime
757     * is set; any switches after that will clear the time.
758     */
759    boolean mDidAppSwitch;
760
761    /**
762     * Set while we are wanting to sleep, to prevent any
763     * activities from being started/resumed.
764     */
765    boolean mSleeping = false;
766
767    /**
768     * Set if we are shutting down the system, similar to sleeping.
769     */
770    boolean mShuttingDown = false;
771
772    /**
773     * Set when the system is going to sleep, until we have
774     * successfully paused the current activity and released our wake lock.
775     * At that point the system is allowed to actually sleep.
776     */
777    PowerManager.WakeLock mGoingToSleep;
778
779    /**
780     * We don't want to allow the device to go to sleep while in the process
781     * of launching an activity.  This is primarily to allow alarm intent
782     * receivers to launch an activity and get that to run before the device
783     * goes back to sleep.
784     */
785    PowerManager.WakeLock mLaunchingActivity;
786
787    /**
788     * Task identifier that activities are currently being started
789     * in.  Incremented each time a new task is created.
790     * todo: Replace this with a TokenSpace class that generates non-repeating
791     * integers that won't wrap.
792     */
793    int mCurTask = 1;
794
795    /**
796     * Current sequence id for oom_adj computation traversal.
797     */
798    int mAdjSeq = 0;
799
800    /**
801     * Set to true if the ANDROID_SIMPLE_PROCESS_MANAGEMENT envvar
802     * is set, indicating the user wants processes started in such a way
803     * that they can use ANDROID_PROCESS_WRAPPER and know what will be
804     * running in each process (thus no pre-initialized process, etc).
805     */
806    boolean mSimpleProcessManagement = false;
807
808    /**
809     * System monitoring: number of processes that died since the last
810     * N procs were started.
811     */
812    int[] mProcDeaths = new int[20];
813
814    String mDebugApp = null;
815    boolean mWaitForDebugger = false;
816    boolean mDebugTransient = false;
817    String mOrigDebugApp = null;
818    boolean mOrigWaitForDebugger = false;
819    boolean mAlwaysFinishActivities = false;
820    IActivityWatcher mWatcher = null;
821
822    /**
823     * Callback of last caller to {@link #requestPss}.
824     */
825    Runnable mRequestPssCallback;
826
827    /**
828     * Remaining processes for which we are waiting results from the last
829     * call to {@link #requestPss}.
830     */
831    final ArrayList<ProcessRecord> mRequestPssList
832            = new ArrayList<ProcessRecord>();
833
834    /**
835     * Runtime statistics collection thread.  This object's lock is used to
836     * protect all related state.
837     */
838    final Thread mProcessStatsThread;
839
840    /**
841     * Used to collect process stats when showing not responding dialog.
842     * Protected by mProcessStatsThread.
843     */
844    final ProcessStats mProcessStats = new ProcessStats(
845            MONITOR_THREAD_CPU_USAGE);
846    long mLastCpuTime = 0;
847    long mLastWriteTime = 0;
848
849    long mInitialStartTime = 0;
850
851    /**
852     * Set to true after the system has finished booting.
853     */
854    boolean mBooted = false;
855
856    int mProcessLimit = 0;
857
858    WindowManagerService mWindowManager;
859
860    static ActivityManagerService mSelf;
861    static ActivityThread mSystemThread;
862
863    private final class AppDeathRecipient implements IBinder.DeathRecipient {
864        final ProcessRecord mApp;
865        final int mPid;
866        final IApplicationThread mAppThread;
867
868        AppDeathRecipient(ProcessRecord app, int pid,
869                IApplicationThread thread) {
870            if (localLOGV) Log.v(
871                TAG, "New death recipient " + this
872                + " for thread " + thread.asBinder());
873            mApp = app;
874            mPid = pid;
875            mAppThread = thread;
876        }
877
878        public void binderDied() {
879            if (localLOGV) Log.v(
880                TAG, "Death received in " + this
881                + " for thread " + mAppThread.asBinder());
882            removeRequestedPss(mApp);
883            synchronized(ActivityManagerService.this) {
884                appDiedLocked(mApp, mPid, mAppThread);
885            }
886        }
887    }
888
889    static final int SHOW_ERROR_MSG = 1;
890    static final int SHOW_NOT_RESPONDING_MSG = 2;
891    static final int SHOW_FACTORY_ERROR_MSG = 3;
892    static final int UPDATE_CONFIGURATION_MSG = 4;
893    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
894    static final int WAIT_FOR_DEBUGGER_MSG = 6;
895    static final int BROADCAST_INTENT_MSG = 7;
896    static final int BROADCAST_TIMEOUT_MSG = 8;
897    static final int PAUSE_TIMEOUT_MSG = 9;
898    static final int IDLE_TIMEOUT_MSG = 10;
899    static final int IDLE_NOW_MSG = 11;
900    static final int SERVICE_TIMEOUT_MSG = 12;
901    static final int UPDATE_TIME_ZONE = 13;
902    static final int SHOW_UID_ERROR_MSG = 14;
903    static final int IM_FEELING_LUCKY_MSG = 15;
904    static final int LAUNCH_TIMEOUT_MSG = 16;
905    static final int DESTROY_TIMEOUT_MSG = 17;
906    static final int SERVICE_ERROR_MSG = 18;
907    static final int RESUME_TOP_ACTIVITY_MSG = 19;
908    static final int PROC_START_TIMEOUT_MSG = 20;
909    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
910
911    AlertDialog mUidAlert;
912
913    final Handler mHandler = new Handler() {
914        //public Handler() {
915        //    if (localLOGV) Log.v(TAG, "Handler started!");
916        //}
917
918        public void handleMessage(Message msg) {
919            switch (msg.what) {
920            case SHOW_ERROR_MSG: {
921                HashMap data = (HashMap) msg.obj;
922                byte[] crashData = (byte[])data.get("crashData");
923                if (crashData != null) {
924                    // This needs to be *un*synchronized to avoid deadlock.
925                    ContentResolver resolver = mContext.getContentResolver();
926                    Checkin.reportCrash(resolver, crashData);
927                }
928                synchronized (ActivityManagerService.this) {
929                    ProcessRecord proc = (ProcessRecord)data.get("app");
930                    if (proc != null && proc.crashDialog != null) {
931                        Log.e(TAG, "App already has crash dialog: " + proc);
932                        return;
933                    }
934                    AppErrorResult res = (AppErrorResult) data.get("result");
935                    if (!mSleeping && !mShuttingDown) {
936                        Dialog d = new AppErrorDialog(
937                                mContext, res, proc,
938                                (Integer)data.get("flags"),
939                                (String)data.get("shortMsg"),
940                                (String)data.get("longMsg"));
941                        d.show();
942                        proc.crashDialog = d;
943                    } else {
944                        // The device is asleep, so just pretend that the user
945                        // saw a crash dialog and hit "force quit".
946                        res.set(0);
947                    }
948                }
949            } break;
950            case SHOW_NOT_RESPONDING_MSG: {
951                synchronized (ActivityManagerService.this) {
952                    HashMap data = (HashMap) msg.obj;
953                    ProcessRecord proc = (ProcessRecord)data.get("app");
954                    if (proc != null && proc.anrDialog != null) {
955                        Log.e(TAG, "App already has anr dialog: " + proc);
956                        return;
957                    }
958
959                    broadcastIntentLocked(null, null, new Intent("android.intent.action.ANR"),
960                            null, null, 0, null, null, null,
961                            false, false, MY_PID, Process.SYSTEM_UID);
962
963                    Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
964                            mContext, proc, (HistoryRecord)data.get("activity"));
965                    d.show();
966                    proc.anrDialog = d;
967                }
968
969                ensureScreenEnabled();
970            } break;
971            case SHOW_FACTORY_ERROR_MSG: {
972                Dialog d = new FactoryErrorDialog(
973                    mContext, msg.getData().getCharSequence("msg"));
974                d.show();
975                enableScreenAfterBoot();
976            } break;
977            case UPDATE_CONFIGURATION_MSG: {
978                final ContentResolver resolver = mContext.getContentResolver();
979                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
980            } break;
981            case GC_BACKGROUND_PROCESSES_MSG: {
982                synchronized (ActivityManagerService.this) {
983                    performAppGcsIfAppropriateLocked();
984                }
985            } break;
986            case WAIT_FOR_DEBUGGER_MSG: {
987                synchronized (ActivityManagerService.this) {
988                    ProcessRecord app = (ProcessRecord)msg.obj;
989                    if (msg.arg1 != 0) {
990                        if (!app.waitedForDebugger) {
991                            Dialog d = new AppWaitingForDebuggerDialog(
992                                    ActivityManagerService.this,
993                                    mContext, app);
994                            app.waitDialog = d;
995                            app.waitedForDebugger = true;
996                            d.show();
997                        }
998                    } else {
999                        if (app.waitDialog != null) {
1000                            app.waitDialog.dismiss();
1001                            app.waitDialog = null;
1002                        }
1003                    }
1004                }
1005            } break;
1006            case BROADCAST_INTENT_MSG: {
1007                if (DEBUG_BROADCAST) Log.v(
1008                        TAG, "Received BROADCAST_INTENT_MSG");
1009                processNextBroadcast(true);
1010            } break;
1011            case BROADCAST_TIMEOUT_MSG: {
1012                broadcastTimeout();
1013            } break;
1014            case PAUSE_TIMEOUT_MSG: {
1015                IBinder token = (IBinder)msg.obj;
1016                // We don't at this point know if the activity is fullscreen,
1017                // so we need to be conservative and assume it isn't.
1018                Log.w(TAG, "Activity pause timeout for " + token);
1019                activityPaused(token, null, true);
1020            } break;
1021            case IDLE_TIMEOUT_MSG: {
1022                IBinder token = (IBinder)msg.obj;
1023                // We don't at this point know if the activity is fullscreen,
1024                // so we need to be conservative and assume it isn't.
1025                Log.w(TAG, "Activity idle timeout for " + token);
1026                activityIdleInternal(token, true);
1027            } break;
1028            case DESTROY_TIMEOUT_MSG: {
1029                IBinder token = (IBinder)msg.obj;
1030                // We don't at this point know if the activity is fullscreen,
1031                // so we need to be conservative and assume it isn't.
1032                Log.w(TAG, "Activity destroy timeout for " + token);
1033                activityDestroyed(token);
1034            } break;
1035            case IDLE_NOW_MSG: {
1036                IBinder token = (IBinder)msg.obj;
1037                activityIdle(token);
1038            } break;
1039            case SERVICE_TIMEOUT_MSG: {
1040                serviceTimeout((ProcessRecord)msg.obj);
1041            } break;
1042            case UPDATE_TIME_ZONE: {
1043                synchronized (ActivityManagerService.this) {
1044                    for (int i = mLRUProcesses.size() - 1 ; i >= 0 ; i--) {
1045                        ProcessRecord r = mLRUProcesses.get(i);
1046                        if (r.thread != null) {
1047                            try {
1048                                r.thread.updateTimeZone();
1049                            } catch (RemoteException ex) {
1050                                Log.w(TAG, "Failed to update time zone for: " + r.info.processName);
1051                            }
1052                        }
1053                    }
1054                }
1055                break;
1056            }
1057            case SHOW_UID_ERROR_MSG: {
1058                // XXX This is a temporary dialog, no need to localize.
1059                AlertDialog d = new BaseErrorDialog(mContext);
1060                d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1061                d.setCancelable(false);
1062                d.setTitle("System UIDs Inconsistent");
1063                d.setMessage("UIDs on the system are inconsistent, you need to wipe your data partition or your device will be unstable.");
1064                d.setButton("I'm Feeling Lucky",
1065                        mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1066                mUidAlert = d;
1067                d.show();
1068            } break;
1069            case IM_FEELING_LUCKY_MSG: {
1070                if (mUidAlert != null) {
1071                    mUidAlert.dismiss();
1072                    mUidAlert = null;
1073                }
1074            } break;
1075            case LAUNCH_TIMEOUT_MSG: {
1076                synchronized (ActivityManagerService.this) {
1077                    if (mLaunchingActivity.isHeld()) {
1078                        Log.w(TAG, "Launch timeout has expired, giving up wake lock!");
1079                        mLaunchingActivity.release();
1080                    }
1081                }
1082            } break;
1083            case SERVICE_ERROR_MSG: {
1084                ServiceRecord srv = (ServiceRecord)msg.obj;
1085                // This needs to be *un*synchronized to avoid deadlock.
1086                Checkin.logEvent(mContext.getContentResolver(),
1087                        Checkin.Events.Tag.SYSTEM_SERVICE_LOOPING,
1088                        srv.name.toShortString());
1089            } break;
1090            case RESUME_TOP_ACTIVITY_MSG: {
1091                synchronized (ActivityManagerService.this) {
1092                    resumeTopActivityLocked(null);
1093                }
1094            }
1095            case PROC_START_TIMEOUT_MSG: {
1096                ProcessRecord app = (ProcessRecord)msg.obj;
1097                synchronized (ActivityManagerService.this) {
1098                    processStartTimedOutLocked(app);
1099                }
1100            }
1101            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1102                synchronized (ActivityManagerService.this) {
1103                    doPendingActivityLaunchesLocked(true);
1104                }
1105            }
1106            }
1107        }
1108    };
1109
1110    public static void setSystemProcess() {
1111        try {
1112            ActivityManagerService m = mSelf;
1113
1114            ServiceManager.addService("activity", m);
1115            ServiceManager.addService("meminfo", new MemBinder(m));
1116            if (MONITOR_CPU_USAGE) {
1117                ServiceManager.addService("cpuinfo", new CpuBinder(m));
1118            }
1119            ServiceManager.addService("activity.broadcasts", new BroadcastsBinder(m));
1120            ServiceManager.addService("activity.services", new ServicesBinder(m));
1121            ServiceManager.addService("activity.senders", new SendersBinder(m));
1122            ServiceManager.addService("activity.providers", new ProvidersBinder(m));
1123            ServiceManager.addService("permission", new PermissionController(m));
1124
1125            ApplicationInfo info =
1126                mSelf.mContext.getPackageManager().getApplicationInfo(
1127                        "android", STOCK_PM_FLAGS);
1128            synchronized (mSelf) {
1129                ProcessRecord app = mSelf.newProcessRecordLocked(
1130                        mSystemThread.getApplicationThread(), info,
1131                        info.processName);
1132                app.persistent = true;
1133                app.pid = Process.myPid();
1134                app.maxAdj = SYSTEM_ADJ;
1135                mSelf.mProcessNames.put(app.processName, app.info.uid, app);
1136                synchronized (mSelf.mPidsSelfLocked) {
1137                    mSelf.mPidsSelfLocked.put(app.pid, app);
1138                }
1139                mSelf.updateLRUListLocked(app, true);
1140            }
1141        } catch (PackageManager.NameNotFoundException e) {
1142            throw new RuntimeException(
1143                    "Unable to find android system package", e);
1144        }
1145    }
1146
1147    public void setWindowManager(WindowManagerService wm) {
1148        mWindowManager = wm;
1149    }
1150
1151    public static final Context main(int factoryTest) {
1152        AThread thr = new AThread();
1153        thr.start();
1154
1155        synchronized (thr) {
1156            while (thr.mService == null) {
1157                try {
1158                    thr.wait();
1159                } catch (InterruptedException e) {
1160                }
1161            }
1162        }
1163
1164        ActivityManagerService m = thr.mService;
1165        mSelf = m;
1166        ActivityThread at = ActivityThread.systemMain();
1167        mSystemThread = at;
1168        Context context = at.getSystemContext();
1169        m.mContext = context;
1170        m.mFactoryTest = factoryTest;
1171        PowerManager pm =
1172            (PowerManager)context.getSystemService(Context.POWER_SERVICE);
1173        m.mGoingToSleep = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Sleep");
1174        m.mLaunchingActivity = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Launch");
1175        m.mLaunchingActivity.setReferenceCounted(false);
1176
1177        m.mBatteryStatsService.publish(context);
1178        m.mUsageStatsService.publish(context);
1179
1180        synchronized (thr) {
1181            thr.mReady = true;
1182            thr.notifyAll();
1183        }
1184
1185        m.startRunning(null, null, null, null);
1186
1187        return context;
1188    }
1189
1190    public static ActivityManagerService self() {
1191        return mSelf;
1192    }
1193
1194    static class AThread extends Thread {
1195        ActivityManagerService mService;
1196        boolean mReady = false;
1197
1198        public AThread() {
1199            super("ActivityManager");
1200        }
1201
1202        public void run() {
1203            Looper.prepare();
1204
1205            android.os.Process.setThreadPriority(
1206                    android.os.Process.THREAD_PRIORITY_FOREGROUND);
1207
1208            ActivityManagerService m = new ActivityManagerService();
1209
1210            synchronized (this) {
1211                mService = m;
1212                notifyAll();
1213            }
1214
1215            synchronized (this) {
1216                while (!mReady) {
1217                    try {
1218                        wait();
1219                    } catch (InterruptedException e) {
1220                    }
1221                }
1222            }
1223
1224            Looper.loop();
1225        }
1226    }
1227
1228    static class BroadcastsBinder extends Binder {
1229        ActivityManagerService mActivityManagerService;
1230        BroadcastsBinder(ActivityManagerService activityManagerService) {
1231            mActivityManagerService = activityManagerService;
1232        }
1233
1234        @Override
1235        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1236            mActivityManagerService.dumpBroadcasts(pw);
1237        }
1238    }
1239
1240    static class ServicesBinder extends Binder {
1241        ActivityManagerService mActivityManagerService;
1242        ServicesBinder(ActivityManagerService activityManagerService) {
1243            mActivityManagerService = activityManagerService;
1244        }
1245
1246        @Override
1247        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1248            mActivityManagerService.dumpServices(pw);
1249        }
1250    }
1251
1252    static class SendersBinder extends Binder {
1253        ActivityManagerService mActivityManagerService;
1254        SendersBinder(ActivityManagerService activityManagerService) {
1255            mActivityManagerService = activityManagerService;
1256        }
1257
1258        @Override
1259        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1260            mActivityManagerService.dumpSenders(pw);
1261        }
1262    }
1263
1264    static class ProvidersBinder extends Binder {
1265        ActivityManagerService mActivityManagerService;
1266        ProvidersBinder(ActivityManagerService activityManagerService) {
1267            mActivityManagerService = activityManagerService;
1268        }
1269
1270        @Override
1271        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1272            mActivityManagerService.dumpProviders(pw);
1273        }
1274    }
1275
1276    static class MemBinder extends Binder {
1277        ActivityManagerService mActivityManagerService;
1278        MemBinder(ActivityManagerService activityManagerService) {
1279            mActivityManagerService = activityManagerService;
1280        }
1281
1282        @Override
1283        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1284            ActivityManagerService service = mActivityManagerService;
1285            ArrayList<ProcessRecord> procs;
1286            synchronized (mActivityManagerService) {
1287                if (args != null && args.length > 0
1288                        && args[0].charAt(0) != '-') {
1289                    procs = new ArrayList<ProcessRecord>();
1290                    int pid = -1;
1291                    try {
1292                        pid = Integer.parseInt(args[0]);
1293                    } catch (NumberFormatException e) {
1294
1295                    }
1296                    for (int i=0; i<service.mLRUProcesses.size(); i++) {
1297                        ProcessRecord proc = service.mLRUProcesses.get(i);
1298                        if (proc.pid == pid) {
1299                            procs.add(proc);
1300                        } else if (proc.processName.equals(args[0])) {
1301                            procs.add(proc);
1302                        }
1303                    }
1304                    if (procs.size() <= 0) {
1305                        pw.println("No process found for: " + args[0]);
1306                        return;
1307                    }
1308                } else {
1309                    procs = service.mLRUProcesses;
1310                }
1311            }
1312            dumpApplicationMemoryUsage(fd, pw, procs, "  ", args);
1313        }
1314    }
1315
1316    static class CpuBinder extends Binder {
1317        ActivityManagerService mActivityManagerService;
1318        CpuBinder(ActivityManagerService activityManagerService) {
1319            mActivityManagerService = activityManagerService;
1320        }
1321
1322        @Override
1323        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1324            synchronized (mActivityManagerService.mProcessStatsThread) {
1325                pw.print(mActivityManagerService.mProcessStats.printCurrentState());
1326            }
1327        }
1328    }
1329
1330    private ActivityManagerService() {
1331        String v = System.getenv("ANDROID_SIMPLE_PROCESS_MANAGEMENT");
1332        if (v != null && Integer.getInteger(v) != 0) {
1333            mSimpleProcessManagement = true;
1334        }
1335        v = System.getenv("ANDROID_DEBUG_APP");
1336        if (v != null) {
1337            mSimpleProcessManagement = true;
1338        }
1339
1340        MY_PID = Process.myPid();
1341
1342        File dataDir = Environment.getDataDirectory();
1343        File systemDir = new File(dataDir, "system");
1344        systemDir.mkdirs();
1345        mBatteryStatsService = new BatteryStatsService(new File(
1346                systemDir, "batterystats.bin").toString());
1347        mBatteryStatsService.getActiveStatistics().readLocked();
1348        mBatteryStatsService.getActiveStatistics().writeLocked();
1349
1350        mUsageStatsService = new UsageStatsService( new File(
1351                systemDir, "usagestats").toString());
1352
1353        mConfiguration.makeDefault();
1354        mProcessStats.init();
1355
1356        // Add ourself to the Watchdog monitors.
1357        Watchdog.getInstance().addMonitor(this);
1358
1359        // These values are set in system/rootdir/init.rc on startup.
1360        FOREGROUND_APP_ADJ =
1361            Integer.valueOf(SystemProperties.get("ro.FOREGROUND_APP_ADJ"));
1362        VISIBLE_APP_ADJ =
1363            Integer.valueOf(SystemProperties.get("ro.VISIBLE_APP_ADJ"));
1364        SECONDARY_SERVER_ADJ =
1365            Integer.valueOf(SystemProperties.get("ro.SECONDARY_SERVER_ADJ"));
1366        BACKUP_APP_ADJ =
1367            Integer.valueOf(SystemProperties.get("ro.BACKUP_APP_ADJ"));
1368        HOME_APP_ADJ =
1369            Integer.valueOf(SystemProperties.get("ro.HOME_APP_ADJ"));
1370        HIDDEN_APP_MIN_ADJ =
1371            Integer.valueOf(SystemProperties.get("ro.HIDDEN_APP_MIN_ADJ"));
1372        CONTENT_PROVIDER_ADJ =
1373            Integer.valueOf(SystemProperties.get("ro.CONTENT_PROVIDER_ADJ"));
1374        HIDDEN_APP_MAX_ADJ = CONTENT_PROVIDER_ADJ-1;
1375        EMPTY_APP_ADJ =
1376            Integer.valueOf(SystemProperties.get("ro.EMPTY_APP_ADJ"));
1377        FOREGROUND_APP_MEM =
1378            Integer.valueOf(SystemProperties.get("ro.FOREGROUND_APP_MEM"))*PAGE_SIZE;
1379        VISIBLE_APP_MEM =
1380            Integer.valueOf(SystemProperties.get("ro.VISIBLE_APP_MEM"))*PAGE_SIZE;
1381        SECONDARY_SERVER_MEM =
1382            Integer.valueOf(SystemProperties.get("ro.SECONDARY_SERVER_MEM"))*PAGE_SIZE;
1383        BACKUP_APP_MEM =
1384            Integer.valueOf(SystemProperties.get("ro.BACKUP_APP_MEM"))*PAGE_SIZE;
1385        HOME_APP_MEM =
1386            Integer.valueOf(SystemProperties.get("ro.HOME_APP_MEM"))*PAGE_SIZE;
1387        HIDDEN_APP_MEM =
1388            Integer.valueOf(SystemProperties.get("ro.HIDDEN_APP_MEM"))*PAGE_SIZE;
1389        EMPTY_APP_MEM =
1390            Integer.valueOf(SystemProperties.get("ro.EMPTY_APP_MEM"))*PAGE_SIZE;
1391
1392        mProcessStatsThread = new Thread("ProcessStats") {
1393            public void run() {
1394                while (true) {
1395                    try {
1396                        try {
1397                            synchronized(this) {
1398                                final long now = SystemClock.uptimeMillis();
1399                                long nextCpuDelay = (mLastCpuTime+MONITOR_CPU_MAX_TIME)-now;
1400                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
1401                                //Log.i(TAG, "Cpu delay=" + nextCpuDelay
1402                                //        + ", write delay=" + nextWriteDelay);
1403                                if (nextWriteDelay < nextCpuDelay) {
1404                                    nextCpuDelay = nextWriteDelay;
1405                                }
1406                                if (nextCpuDelay > 0) {
1407                                    this.wait(nextCpuDelay);
1408                                }
1409                            }
1410                        } catch (InterruptedException e) {
1411                        }
1412
1413                        updateCpuStatsNow();
1414                    } catch (Exception e) {
1415                        Log.e(TAG, "Unexpected exception collecting process stats", e);
1416                    }
1417                }
1418            }
1419        };
1420        mProcessStatsThread.start();
1421    }
1422
1423    @Override
1424    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
1425            throws RemoteException {
1426        try {
1427            return super.onTransact(code, data, reply, flags);
1428        } catch (RuntimeException e) {
1429            // The activity manager only throws security exceptions, so let's
1430            // log all others.
1431            if (!(e instanceof SecurityException)) {
1432                Log.e(TAG, "Activity Manager Crash", e);
1433            }
1434            throw e;
1435        }
1436    }
1437
1438    void updateCpuStats() {
1439        synchronized (mProcessStatsThread) {
1440            final long now = SystemClock.uptimeMillis();
1441            if (mLastCpuTime < (now-MONITOR_CPU_MIN_TIME)) {
1442                mProcessStatsThread.notify();
1443            }
1444        }
1445    }
1446
1447    void updateCpuStatsNow() {
1448        synchronized (mProcessStatsThread) {
1449            final long now = SystemClock.uptimeMillis();
1450            boolean haveNewCpuStats = false;
1451
1452            if (MONITOR_CPU_USAGE &&
1453                    mLastCpuTime < (now-MONITOR_CPU_MIN_TIME)) {
1454                mLastCpuTime = now;
1455                haveNewCpuStats = true;
1456                mProcessStats.update();
1457                //Log.i(TAG, mProcessStats.printCurrentState());
1458                //Log.i(TAG, "Total CPU usage: "
1459                //        + mProcessStats.getTotalCpuPercent() + "%");
1460
1461                // Log the cpu usage if the property is set.
1462                if ("true".equals(SystemProperties.get("events.cpu"))) {
1463                    int user = mProcessStats.getLastUserTime();
1464                    int system = mProcessStats.getLastSystemTime();
1465                    int iowait = mProcessStats.getLastIoWaitTime();
1466                    int irq = mProcessStats.getLastIrqTime();
1467                    int softIrq = mProcessStats.getLastSoftIrqTime();
1468                    int idle = mProcessStats.getLastIdleTime();
1469
1470                    int total = user + system + iowait + irq + softIrq + idle;
1471                    if (total == 0) total = 1;
1472
1473                    EventLog.writeEvent(LOG_CPU,
1474                            ((user+system+iowait+irq+softIrq) * 100) / total,
1475                            (user * 100) / total,
1476                            (system * 100) / total,
1477                            (iowait * 100) / total,
1478                            (irq * 100) / total,
1479                            (softIrq * 100) / total);
1480                }
1481            }
1482
1483            synchronized(mBatteryStatsService.getActiveStatistics()) {
1484                synchronized(mPidsSelfLocked) {
1485                    if (haveNewCpuStats) {
1486                        if (mBatteryStatsService.isOnBattery()) {
1487                            final int N = mProcessStats.countWorkingStats();
1488                            for (int i=0; i<N; i++) {
1489                                ProcessStats.Stats st
1490                                        = mProcessStats.getWorkingStats(i);
1491                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
1492                                if (pr != null) {
1493                                    BatteryStatsImpl.Uid.Proc ps = pr.batteryStats;
1494                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
1495                                }
1496                            }
1497                        }
1498                    }
1499                }
1500
1501                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
1502                    mLastWriteTime = now;
1503                    mBatteryStatsService.getActiveStatistics().writeLocked();
1504                }
1505            }
1506        }
1507    }
1508
1509    /**
1510     * Initialize the application bind args. These are passed to each
1511     * process when the bindApplication() IPC is sent to the process. They're
1512     * lazily setup to make sure the services are running when they're asked for.
1513     */
1514    private HashMap<String, IBinder> getCommonServicesLocked() {
1515        if (mAppBindArgs == null) {
1516            mAppBindArgs = new HashMap<String, IBinder>();
1517
1518            // Setup the application init args
1519            mAppBindArgs.put("package", ServiceManager.getService("package"));
1520            mAppBindArgs.put("window", ServiceManager.getService("window"));
1521            mAppBindArgs.put(Context.ALARM_SERVICE,
1522                    ServiceManager.getService(Context.ALARM_SERVICE));
1523        }
1524        return mAppBindArgs;
1525    }
1526
1527    private final void setFocusedActivityLocked(HistoryRecord r) {
1528        if (mFocusedActivity != r) {
1529            mFocusedActivity = r;
1530            mWindowManager.setFocusedApp(r, true);
1531        }
1532    }
1533
1534    private final void updateLRUListLocked(ProcessRecord app,
1535            boolean oomAdj) {
1536        // put it on the LRU to keep track of when it should be exited.
1537        int lrui = mLRUProcesses.indexOf(app);
1538        if (lrui >= 0) mLRUProcesses.remove(lrui);
1539        mLRUProcesses.add(app);
1540        //Log.i(TAG, "Putting proc to front: " + app.processName);
1541        if (oomAdj) {
1542            updateOomAdjLocked();
1543        }
1544    }
1545
1546    private final boolean updateLRUListLocked(HistoryRecord r) {
1547        final boolean hadit = mLRUActivities.remove(r);
1548        mLRUActivities.add(r);
1549        return hadit;
1550    }
1551
1552    private final HistoryRecord topRunningActivityLocked(HistoryRecord notTop) {
1553        int i = mHistory.size()-1;
1554        while (i >= 0) {
1555            HistoryRecord r = (HistoryRecord)mHistory.get(i);
1556            if (!r.finishing && r != notTop) {
1557                return r;
1558            }
1559            i--;
1560        }
1561        return null;
1562    }
1563
1564    private final HistoryRecord topRunningNonDelayedActivityLocked(HistoryRecord notTop) {
1565        int i = mHistory.size()-1;
1566        while (i >= 0) {
1567            HistoryRecord r = (HistoryRecord)mHistory.get(i);
1568            if (!r.finishing && !r.delayedResume && r != notTop) {
1569                return r;
1570            }
1571            i--;
1572        }
1573        return null;
1574    }
1575
1576    /**
1577     * This is a simplified version of topRunningActivityLocked that provides a number of
1578     * optional skip-over modes.  It is intended for use with the ActivityWatcher hook only.
1579     *
1580     * @param token If non-null, any history records matching this token will be skipped.
1581     * @param taskId If non-zero, we'll attempt to skip over records with the same task ID.
1582     *
1583     * @return Returns the HistoryRecord of the next activity on the stack.
1584     */
1585    private final HistoryRecord topRunningActivityLocked(IBinder token, int taskId) {
1586        int i = mHistory.size()-1;
1587        while (i >= 0) {
1588            HistoryRecord r = (HistoryRecord)mHistory.get(i);
1589            // Note: the taskId check depends on real taskId fields being non-zero
1590            if (!r.finishing && (token != r) && (taskId != r.task.taskId)) {
1591                return r;
1592            }
1593            i--;
1594        }
1595        return null;
1596    }
1597
1598    private final ProcessRecord getProcessRecordLocked(
1599            String processName, int uid) {
1600        if (uid == Process.SYSTEM_UID) {
1601            // The system gets to run in any process.  If there are multiple
1602            // processes with the same uid, just pick the first (this
1603            // should never happen).
1604            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(
1605                    processName);
1606            return procs != null ? procs.valueAt(0) : null;
1607        }
1608        ProcessRecord proc = mProcessNames.get(processName, uid);
1609        return proc;
1610    }
1611
1612    private boolean isNextTransitionForward() {
1613        int transit = mWindowManager.getPendingAppTransition();
1614        return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
1615                || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
1616                || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT;
1617    }
1618
1619    private final boolean realStartActivityLocked(HistoryRecord r,
1620            ProcessRecord app, boolean andResume, boolean checkConfig)
1621            throws RemoteException {
1622
1623        r.startFreezingScreenLocked(app, 0);
1624        mWindowManager.setAppVisibility(r, true);
1625
1626        // Have the window manager re-evaluate the orientation of
1627        // the screen based on the new activity order.  Note that
1628        // as a result of this, it can call back into the activity
1629        // manager with a new orientation.  We don't care about that,
1630        // because the activity is not currently running so we are
1631        // just restarting it anyway.
1632        if (checkConfig) {
1633            Configuration config = mWindowManager.updateOrientationFromAppTokens(
1634                    mConfiguration,
1635                    r.mayFreezeScreenLocked(app) ? r : null);
1636            updateConfigurationLocked(config, r);
1637        }
1638
1639        r.app = app;
1640
1641        if (localLOGV) Log.v(TAG, "Launching: " + r);
1642
1643        int idx = app.activities.indexOf(r);
1644        if (idx < 0) {
1645            app.activities.add(r);
1646        }
1647        updateLRUListLocked(app, true);
1648
1649        try {
1650            if (app.thread == null) {
1651                throw new RemoteException();
1652            }
1653            List<ResultInfo> results = null;
1654            List<Intent> newIntents = null;
1655            if (andResume) {
1656                results = r.results;
1657                newIntents = r.newIntents;
1658            }
1659            if (DEBUG_SWITCH) Log.v(TAG, "Launching: " + r
1660                    + " icicle=" + r.icicle
1661                    + " with results=" + results + " newIntents=" + newIntents
1662                    + " andResume=" + andResume);
1663            if (andResume) {
1664                EventLog.writeEvent(LOG_AM_RESTART_ACTIVITY,
1665                        System.identityHashCode(r),
1666                        r.task.taskId, r.shortComponentName);
1667            }
1668            if (r.isHomeActivity) {
1669                mHomeProcess = app;
1670            }
1671            app.thread.scheduleLaunchActivity(new Intent(r.intent), r,
1672                    r.info, r.icicle, results, newIntents, !andResume,
1673                    isNextTransitionForward());
1674            // Update usage stats for launched activity
1675            updateUsageStats(r, true);
1676        } catch (RemoteException e) {
1677            if (r.launchFailed) {
1678                // This is the second time we failed -- finish activity
1679                // and give up.
1680                Log.e(TAG, "Second failure launching "
1681                      + r.intent.getComponent().flattenToShortString()
1682                      + ", giving up", e);
1683                appDiedLocked(app, app.pid, app.thread);
1684                requestFinishActivityLocked(r, Activity.RESULT_CANCELED, null,
1685                        "2nd-crash");
1686                return false;
1687            }
1688
1689            // This is the first time we failed -- restart process and
1690            // retry.
1691            app.activities.remove(r);
1692            throw e;
1693        }
1694
1695        r.launchFailed = false;
1696        if (updateLRUListLocked(r)) {
1697            Log.w(TAG, "Activity " + r
1698                  + " being launched, but already in LRU list");
1699        }
1700
1701        if (andResume) {
1702            // As part of the process of launching, ActivityThread also performs
1703            // a resume.
1704            r.state = ActivityState.RESUMED;
1705            r.icicle = null;
1706            r.haveState = false;
1707            r.stopped = false;
1708            mResumedActivity = r;
1709            r.task.touchActiveTime();
1710            completeResumeLocked(r);
1711            pauseIfSleepingLocked();
1712        } else {
1713            // This activity is not starting in the resumed state... which
1714            // should look like we asked it to pause+stop (but remain visible),
1715            // and it has done so and reported back the current icicle and
1716            // other state.
1717            r.state = ActivityState.STOPPED;
1718            r.stopped = true;
1719        }
1720
1721        return true;
1722    }
1723
1724    private final void startSpecificActivityLocked(HistoryRecord r,
1725            boolean andResume, boolean checkConfig) {
1726        // Is this activity's application already running?
1727        ProcessRecord app = getProcessRecordLocked(r.processName,
1728                r.info.applicationInfo.uid);
1729
1730        if (r.startTime == 0) {
1731            r.startTime = SystemClock.uptimeMillis();
1732            if (mInitialStartTime == 0) {
1733                mInitialStartTime = r.startTime;
1734            }
1735        } else if (mInitialStartTime == 0) {
1736            mInitialStartTime = SystemClock.uptimeMillis();
1737        }
1738
1739        if (app != null && app.thread != null) {
1740            try {
1741                realStartActivityLocked(r, app, andResume, checkConfig);
1742                return;
1743            } catch (RemoteException e) {
1744                Log.w(TAG, "Exception when starting activity "
1745                        + r.intent.getComponent().flattenToShortString(), e);
1746            }
1747
1748            // If a dead object exception was thrown -- fall through to
1749            // restart the application.
1750        }
1751
1752        startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
1753                "activity", r.intent.getComponent());
1754    }
1755
1756    private final ProcessRecord startProcessLocked(String processName,
1757            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
1758            String hostingType, ComponentName hostingName) {
1759        ProcessRecord app = getProcessRecordLocked(processName, info.uid);
1760        // We don't have to do anything more if:
1761        // (1) There is an existing application record; and
1762        // (2) The caller doesn't think it is dead, OR there is no thread
1763        //     object attached to it so we know it couldn't have crashed; and
1764        // (3) There is a pid assigned to it, so it is either starting or
1765        //     already running.
1766        if (DEBUG_PROCESSES) Log.v(TAG, "startProcess: name=" + processName
1767                + " app=" + app + " knownToBeDead=" + knownToBeDead
1768                + " thread=" + (app != null ? app.thread : null)
1769                + " pid=" + (app != null ? app.pid : -1));
1770        if (app != null &&
1771                (!knownToBeDead || app.thread == null) && app.pid > 0) {
1772            return app;
1773        }
1774
1775        String hostingNameStr = hostingName != null
1776                ? hostingName.flattenToShortString() : null;
1777
1778        if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
1779            // If we are in the background, then check to see if this process
1780            // is bad.  If so, we will just silently fail.
1781            if (mBadProcesses.get(info.processName, info.uid) != null) {
1782                return null;
1783            }
1784        } else {
1785            // When the user is explicitly starting a process, then clear its
1786            // crash count so that we won't make it bad until they see at
1787            // least one crash dialog again, and make the process good again
1788            // if it had been bad.
1789            mProcessCrashTimes.remove(info.processName, info.uid);
1790            if (mBadProcesses.get(info.processName, info.uid) != null) {
1791                EventLog.writeEvent(LOG_AM_PROCESS_GOOD, info.uid,
1792                        info.processName);
1793                mBadProcesses.remove(info.processName, info.uid);
1794                if (app != null) {
1795                    app.bad = false;
1796                }
1797            }
1798        }
1799
1800        if (app == null) {
1801            app = newProcessRecordLocked(null, info, processName);
1802            mProcessNames.put(processName, info.uid, app);
1803        } else {
1804            // If this is a new package in the process, add the package to the list
1805            app.addPackage(info.packageName);
1806        }
1807
1808        // If the system is not ready yet, then hold off on starting this
1809        // process until it is.
1810        if (!mSystemReady
1811                && (info.flags&ApplicationInfo.FLAG_PERSISTENT) == 0) {
1812            if (!mProcessesOnHold.contains(app)) {
1813                mProcessesOnHold.add(app);
1814            }
1815            return app;
1816        }
1817
1818        startProcessLocked(app, hostingType, hostingNameStr);
1819        return (app.pid != 0) ? app : null;
1820    }
1821
1822    private final void startProcessLocked(ProcessRecord app,
1823            String hostingType, String hostingNameStr) {
1824        if (app.pid > 0 && app.pid != MY_PID) {
1825            synchronized (mPidsSelfLocked) {
1826                mPidsSelfLocked.remove(app.pid);
1827                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
1828            }
1829            app.pid = 0;
1830        }
1831
1832        mProcessesOnHold.remove(app);
1833
1834        updateCpuStats();
1835
1836        System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1);
1837        mProcDeaths[0] = 0;
1838
1839        try {
1840            int uid = app.info.uid;
1841            int[] gids = null;
1842            try {
1843                gids = mContext.getPackageManager().getPackageGids(
1844                        app.info.packageName);
1845            } catch (PackageManager.NameNotFoundException e) {
1846                Log.w(TAG, "Unable to retrieve gids", e);
1847            }
1848            if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
1849                if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
1850                        && mTopComponent != null
1851                        && app.processName.equals(mTopComponent.getPackageName())) {
1852                    uid = 0;
1853                }
1854                if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
1855                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
1856                    uid = 0;
1857                }
1858            }
1859            int debugFlags = 0;
1860            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
1861                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
1862            }
1863            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
1864                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
1865            }
1866            if ("1".equals(SystemProperties.get("debug.assert"))) {
1867                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
1868            }
1869            int pid = Process.start("android.app.ActivityThread",
1870                    mSimpleProcessManagement ? app.processName : null, uid, uid,
1871                    gids, debugFlags, null);
1872            BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
1873            synchronized (bs) {
1874                if (bs.isOnBattery()) {
1875                    app.batteryStats.incStartsLocked();
1876                }
1877            }
1878
1879            EventLog.writeEvent(LOG_AM_PROCESS_START, pid, uid,
1880                    app.processName, hostingType,
1881                    hostingNameStr != null ? hostingNameStr : "");
1882
1883            if (app.persistent) {
1884                Watchdog.getInstance().processStarted(app, app.processName, pid);
1885            }
1886
1887            StringBuilder buf = mStringBuilder;
1888            buf.setLength(0);
1889            buf.append("Start proc ");
1890            buf.append(app.processName);
1891            buf.append(" for ");
1892            buf.append(hostingType);
1893            if (hostingNameStr != null) {
1894                buf.append(" ");
1895                buf.append(hostingNameStr);
1896            }
1897            buf.append(": pid=");
1898            buf.append(pid);
1899            buf.append(" uid=");
1900            buf.append(uid);
1901            buf.append(" gids={");
1902            if (gids != null) {
1903                for (int gi=0; gi<gids.length; gi++) {
1904                    if (gi != 0) buf.append(", ");
1905                    buf.append(gids[gi]);
1906
1907                }
1908            }
1909            buf.append("}");
1910            Log.i(TAG, buf.toString());
1911            if (pid == 0 || pid == MY_PID) {
1912                // Processes are being emulated with threads.
1913                app.pid = MY_PID;
1914                app.removed = false;
1915                mStartingProcesses.add(app);
1916            } else if (pid > 0) {
1917                app.pid = pid;
1918                app.removed = false;
1919                synchronized (mPidsSelfLocked) {
1920                    this.mPidsSelfLocked.put(pid, app);
1921                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1922                    msg.obj = app;
1923                    mHandler.sendMessageDelayed(msg, PROC_START_TIMEOUT);
1924                }
1925            } else {
1926                app.pid = 0;
1927                RuntimeException e = new RuntimeException(
1928                        "Failure starting process " + app.processName
1929                        + ": returned pid=" + pid);
1930                Log.e(TAG, e.getMessage(), e);
1931            }
1932        } catch (RuntimeException e) {
1933            // XXX do better error recovery.
1934            app.pid = 0;
1935            Log.e(TAG, "Failure starting process " + app.processName, e);
1936        }
1937    }
1938
1939    private final void startPausingLocked(boolean userLeaving, boolean uiSleeping) {
1940        if (mPausingActivity != null) {
1941            RuntimeException e = new RuntimeException();
1942            Log.e(TAG, "Trying to pause when pause is already pending for "
1943                  + mPausingActivity, e);
1944        }
1945        HistoryRecord prev = mResumedActivity;
1946        if (prev == null) {
1947            RuntimeException e = new RuntimeException();
1948            Log.e(TAG, "Trying to pause when nothing is resumed", e);
1949            resumeTopActivityLocked(null);
1950            return;
1951        }
1952        if (DEBUG_PAUSE) Log.v(TAG, "Start pausing: " + prev);
1953        mResumedActivity = null;
1954        mPausingActivity = prev;
1955        mLastPausedActivity = prev;
1956        prev.state = ActivityState.PAUSING;
1957        prev.task.touchActiveTime();
1958
1959        updateCpuStats();
1960
1961        if (prev.app != null && prev.app.thread != null) {
1962            if (DEBUG_PAUSE) Log.v(TAG, "Enqueueing pending pause: " + prev);
1963            try {
1964                EventLog.writeEvent(LOG_AM_PAUSE_ACTIVITY,
1965                        System.identityHashCode(prev),
1966                        prev.shortComponentName);
1967                prev.app.thread.schedulePauseActivity(prev, prev.finishing, userLeaving,
1968                        prev.configChangeFlags);
1969                updateUsageStats(prev, false);
1970            } catch (Exception e) {
1971                // Ignore exception, if process died other code will cleanup.
1972                Log.w(TAG, "Exception thrown during pause", e);
1973                mPausingActivity = null;
1974                mLastPausedActivity = null;
1975            }
1976        } else {
1977            mPausingActivity = null;
1978            mLastPausedActivity = null;
1979        }
1980
1981        // If we are not going to sleep, we want to ensure the device is
1982        // awake until the next activity is started.
1983        if (!mSleeping && !mShuttingDown) {
1984            mLaunchingActivity.acquire();
1985            if (!mHandler.hasMessages(LAUNCH_TIMEOUT_MSG)) {
1986                // To be safe, don't allow the wake lock to be held for too long.
1987                Message msg = mHandler.obtainMessage(LAUNCH_TIMEOUT_MSG);
1988                mHandler.sendMessageDelayed(msg, LAUNCH_TIMEOUT);
1989            }
1990        }
1991
1992
1993        if (mPausingActivity != null) {
1994            // Have the window manager pause its key dispatching until the new
1995            // activity has started.  If we're pausing the activity just because
1996            // the screen is being turned off and the UI is sleeping, don't interrupt
1997            // key dispatch; the same activity will pick it up again on wakeup.
1998            if (!uiSleeping) {
1999                prev.pauseKeyDispatchingLocked();
2000            } else {
2001                if (DEBUG_PAUSE) Log.v(TAG, "Key dispatch not paused for screen off");
2002            }
2003
2004            // Schedule a pause timeout in case the app doesn't respond.
2005            // We don't give it much time because this directly impacts the
2006            // responsiveness seen by the user.
2007            Message msg = mHandler.obtainMessage(PAUSE_TIMEOUT_MSG);
2008            msg.obj = prev;
2009            mHandler.sendMessageDelayed(msg, PAUSE_TIMEOUT);
2010            if (DEBUG_PAUSE) Log.v(TAG, "Waiting for pause to complete...");
2011        } else {
2012            // This activity failed to schedule the
2013            // pause, so just treat it as being paused now.
2014            if (DEBUG_PAUSE) Log.v(TAG, "Activity not running, resuming next.");
2015            resumeTopActivityLocked(null);
2016        }
2017    }
2018
2019    private final void completePauseLocked() {
2020        HistoryRecord prev = mPausingActivity;
2021        if (DEBUG_PAUSE) Log.v(TAG, "Complete pause: " + prev);
2022
2023        if (prev != null) {
2024            if (prev.finishing) {
2025                if (DEBUG_PAUSE) Log.v(TAG, "Executing finish of activity: " + prev);
2026                prev = finishCurrentActivityLocked(prev, FINISH_AFTER_VISIBLE);
2027            } else if (prev.app != null) {
2028                if (DEBUG_PAUSE) Log.v(TAG, "Enqueueing pending stop: " + prev);
2029                if (prev.waitingVisible) {
2030                    prev.waitingVisible = false;
2031                    mWaitingVisibleActivities.remove(prev);
2032                    if (DEBUG_SWITCH || DEBUG_PAUSE) Log.v(
2033                            TAG, "Complete pause, no longer waiting: " + prev);
2034                }
2035                if (prev.configDestroy) {
2036                    // The previous is being paused because the configuration
2037                    // is changing, which means it is actually stopping...
2038                    // To juggle the fact that we are also starting a new
2039                    // instance right now, we need to first completely stop
2040                    // the current instance before starting the new one.
2041                    if (DEBUG_PAUSE) Log.v(TAG, "Destroying after pause: " + prev);
2042                    destroyActivityLocked(prev, true);
2043                } else {
2044                    mStoppingActivities.add(prev);
2045                    if (mStoppingActivities.size() > 3) {
2046                        // If we already have a few activities waiting to stop,
2047                        // then give up on things going idle and start clearing
2048                        // them out.
2049                        if (DEBUG_PAUSE) Log.v(TAG, "To many pending stops, forcing idle");
2050                        Message msg = Message.obtain();
2051                        msg.what = ActivityManagerService.IDLE_NOW_MSG;
2052                        mHandler.sendMessage(msg);
2053                    }
2054                }
2055            } else {
2056                if (DEBUG_PAUSE) Log.v(TAG, "App died during pause, not stopping: " + prev);
2057                prev = null;
2058            }
2059            mPausingActivity = null;
2060        }
2061
2062        if (!mSleeping && !mShuttingDown) {
2063            resumeTopActivityLocked(prev);
2064        } else {
2065            if (mGoingToSleep.isHeld()) {
2066                mGoingToSleep.release();
2067            }
2068            if (mShuttingDown) {
2069                notifyAll();
2070            }
2071        }
2072
2073        if (prev != null) {
2074            prev.resumeKeyDispatchingLocked();
2075        }
2076
2077        if (prev.app != null && prev.cpuTimeAtResume > 0 && mBatteryStatsService.isOnBattery()) {
2078            long diff = 0;
2079            synchronized (mProcessStatsThread) {
2080                diff = mProcessStats.getCpuTimeForPid(prev.app.pid) - prev.cpuTimeAtResume;
2081            }
2082            if (diff > 0) {
2083                BatteryStatsImpl bsi = mBatteryStatsService.getActiveStatistics();
2084                synchronized (bsi) {
2085                    BatteryStatsImpl.Uid.Proc ps =
2086                            bsi.getProcessStatsLocked(prev.info.applicationInfo.uid,
2087                            prev.info.packageName);
2088                    if (ps != null) {
2089                        ps.addForegroundTimeLocked(diff);
2090                    }
2091                }
2092            }
2093        }
2094        prev.cpuTimeAtResume = 0; // reset it
2095    }
2096
2097    /**
2098     * Once we know that we have asked an application to put an activity in
2099     * the resumed state (either by launching it or explicitly telling it),
2100     * this function updates the rest of our state to match that fact.
2101     */
2102    private final void completeResumeLocked(HistoryRecord next) {
2103        next.idle = false;
2104        next.results = null;
2105        next.newIntents = null;
2106
2107        // schedule an idle timeout in case the app doesn't do it for us.
2108        Message msg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG);
2109        msg.obj = next;
2110        mHandler.sendMessageDelayed(msg, IDLE_TIMEOUT);
2111
2112        if (false) {
2113            // The activity was never told to pause, so just keep
2114            // things going as-is.  To maintain our own state,
2115            // we need to emulate it coming back and saying it is
2116            // idle.
2117            msg = mHandler.obtainMessage(IDLE_NOW_MSG);
2118            msg.obj = next;
2119            mHandler.sendMessage(msg);
2120        }
2121
2122        next.thumbnail = null;
2123        setFocusedActivityLocked(next);
2124        next.resumeKeyDispatchingLocked();
2125        ensureActivitiesVisibleLocked(null, 0);
2126        mWindowManager.executeAppTransition();
2127
2128        // Mark the point when the activity is resuming
2129        // TODO: To be more accurate, the mark should be before the onCreate,
2130        //       not after the onResume. But for subsequent starts, onResume is fine.
2131        if (next.app != null) {
2132            synchronized (mProcessStatsThread) {
2133                next.cpuTimeAtResume = mProcessStats.getCpuTimeForPid(next.app.pid);
2134            }
2135        } else {
2136            next.cpuTimeAtResume = 0; // Couldn't get the cpu time of process
2137        }
2138    }
2139
2140    /**
2141     * Make sure that all activities that need to be visible (that is, they
2142     * currently can be seen by the user) actually are.
2143     */
2144    private final void ensureActivitiesVisibleLocked(HistoryRecord top,
2145            HistoryRecord starting, String onlyThisProcess, int configChanges) {
2146        if (DEBUG_VISBILITY) Log.v(
2147                TAG, "ensureActivitiesVisible behind " + top
2148                + " configChanges=0x" + Integer.toHexString(configChanges));
2149
2150        // If the top activity is not fullscreen, then we need to
2151        // make sure any activities under it are now visible.
2152        final int count = mHistory.size();
2153        int i = count-1;
2154        while (mHistory.get(i) != top) {
2155            i--;
2156        }
2157        HistoryRecord r;
2158        boolean behindFullscreen = false;
2159        for (; i>=0; i--) {
2160            r = (HistoryRecord)mHistory.get(i);
2161            if (DEBUG_VISBILITY) Log.v(
2162                    TAG, "Make visible? " + r + " finishing=" + r.finishing
2163                    + " state=" + r.state);
2164            if (r.finishing) {
2165                continue;
2166            }
2167
2168            final boolean doThisProcess = onlyThisProcess == null
2169                    || onlyThisProcess.equals(r.processName);
2170
2171            // First: if this is not the current activity being started, make
2172            // sure it matches the current configuration.
2173            if (r != starting && doThisProcess) {
2174                ensureActivityConfigurationLocked(r, 0);
2175            }
2176
2177            if (r.app == null || r.app.thread == null) {
2178                if (onlyThisProcess == null
2179                        || onlyThisProcess.equals(r.processName)) {
2180                    // This activity needs to be visible, but isn't even
2181                    // running...  get it started, but don't resume it
2182                    // at this point.
2183                    if (DEBUG_VISBILITY) Log.v(
2184                            TAG, "Start and freeze screen for " + r);
2185                    if (r != starting) {
2186                        r.startFreezingScreenLocked(r.app, configChanges);
2187                    }
2188                    if (!r.visible) {
2189                        if (DEBUG_VISBILITY) Log.v(
2190                                TAG, "Starting and making visible: " + r);
2191                        mWindowManager.setAppVisibility(r, true);
2192                    }
2193                    if (r != starting) {
2194                        startSpecificActivityLocked(r, false, false);
2195                    }
2196                }
2197
2198            } else if (r.visible) {
2199                // If this activity is already visible, then there is nothing
2200                // else to do here.
2201                if (DEBUG_VISBILITY) Log.v(
2202                        TAG, "Skipping: already visible at " + r);
2203                r.stopFreezingScreenLocked(false);
2204
2205            } else if (onlyThisProcess == null) {
2206                // This activity is not currently visible, but is running.
2207                // Tell it to become visible.
2208                r.visible = true;
2209                if (r.state != ActivityState.RESUMED && r != starting) {
2210                    // If this activity is paused, tell it
2211                    // to now show its window.
2212                    if (DEBUG_VISBILITY) Log.v(
2213                            TAG, "Making visible and scheduling visibility: " + r);
2214                    try {
2215                        mWindowManager.setAppVisibility(r, true);
2216                        r.app.thread.scheduleWindowVisibility(r, true);
2217                        r.stopFreezingScreenLocked(false);
2218                    } catch (Exception e) {
2219                        // Just skip on any failure; we'll make it
2220                        // visible when it next restarts.
2221                        Log.w(TAG, "Exception thrown making visibile: "
2222                                + r.intent.getComponent(), e);
2223                    }
2224                }
2225            }
2226
2227            // Aggregate current change flags.
2228            configChanges |= r.configChangeFlags;
2229
2230            if (r.fullscreen) {
2231                // At this point, nothing else needs to be shown
2232                if (DEBUG_VISBILITY) Log.v(
2233                        TAG, "Stopping: fullscreen at " + r);
2234                behindFullscreen = true;
2235                i--;
2236                break;
2237            }
2238        }
2239
2240        // Now for any activities that aren't visible to the user, make
2241        // sure they no longer are keeping the screen frozen.
2242        while (i >= 0) {
2243            r = (HistoryRecord)mHistory.get(i);
2244            if (DEBUG_VISBILITY) Log.v(
2245                    TAG, "Make invisible? " + r + " finishing=" + r.finishing
2246                    + " state=" + r.state
2247                    + " behindFullscreen=" + behindFullscreen);
2248            if (!r.finishing) {
2249                if (behindFullscreen) {
2250                    if (r.visible) {
2251                        if (DEBUG_VISBILITY) Log.v(
2252                                TAG, "Making invisible: " + r);
2253                        r.visible = false;
2254                        try {
2255                            mWindowManager.setAppVisibility(r, false);
2256                            if ((r.state == ActivityState.STOPPING
2257                                    || r.state == ActivityState.STOPPED)
2258                                    && r.app != null && r.app.thread != null) {
2259                                if (DEBUG_VISBILITY) Log.v(
2260                                        TAG, "Scheduling invisibility: " + r);
2261                                r.app.thread.scheduleWindowVisibility(r, false);
2262                            }
2263                        } catch (Exception e) {
2264                            // Just skip on any failure; we'll make it
2265                            // visible when it next restarts.
2266                            Log.w(TAG, "Exception thrown making hidden: "
2267                                    + r.intent.getComponent(), e);
2268                        }
2269                    } else {
2270                        if (DEBUG_VISBILITY) Log.v(
2271                                TAG, "Already invisible: " + r);
2272                    }
2273                } else if (r.fullscreen) {
2274                    if (DEBUG_VISBILITY) Log.v(
2275                            TAG, "Now behindFullscreen: " + r);
2276                    behindFullscreen = true;
2277                }
2278            }
2279            i--;
2280        }
2281    }
2282
2283    /**
2284     * Version of ensureActivitiesVisible that can easily be called anywhere.
2285     */
2286    private final void ensureActivitiesVisibleLocked(HistoryRecord starting,
2287            int configChanges) {
2288        HistoryRecord r = topRunningActivityLocked(null);
2289        if (r != null) {
2290            ensureActivitiesVisibleLocked(r, starting, null, configChanges);
2291        }
2292    }
2293
2294    private void updateUsageStats(HistoryRecord resumedComponent, boolean resumed) {
2295        if (resumed) {
2296            mUsageStatsService.noteResumeComponent(resumedComponent.realActivity);
2297        } else {
2298            mUsageStatsService.notePauseComponent(resumedComponent.realActivity);
2299        }
2300    }
2301
2302    /**
2303     * Ensure that the top activity in the stack is resumed.
2304     *
2305     * @param prev The previously resumed activity, for when in the process
2306     * of pausing; can be null to call from elsewhere.
2307     *
2308     * @return Returns true if something is being resumed, or false if
2309     * nothing happened.
2310     */
2311    private final boolean resumeTopActivityLocked(HistoryRecord prev) {
2312        // Find the first activity that is not finishing.
2313        HistoryRecord next = topRunningActivityLocked(null);
2314
2315        // Remember how we'll process this pause/resume situation, and ensure
2316        // that the state is reset however we wind up proceeding.
2317        final boolean userLeaving = mUserLeaving;
2318        mUserLeaving = false;
2319
2320        if (next == null) {
2321            // There are no more activities!  Let's just start up the
2322            // Launcher...
2323            if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2324                    && mTopAction == null) {
2325                // We are running in factory test mode, but unable to find
2326                // the factory test app, so just sit around displaying the
2327                // error message and don't try to start anything.
2328                return false;
2329            }
2330            Intent intent = new Intent(
2331                mTopAction,
2332                mTopData != null ? Uri.parse(mTopData) : null);
2333            intent.setComponent(mTopComponent);
2334            if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
2335                intent.addCategory(Intent.CATEGORY_HOME);
2336            }
2337            ActivityInfo aInfo =
2338                intent.resolveActivityInfo(mContext.getPackageManager(),
2339                        STOCK_PM_FLAGS);
2340            if (aInfo != null) {
2341                intent.setComponent(new ComponentName(
2342                        aInfo.applicationInfo.packageName, aInfo.name));
2343                // Don't do this if the home app is currently being
2344                // instrumented.
2345                ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2346                        aInfo.applicationInfo.uid);
2347                if (app == null || app.instrumentationClass == null) {
2348                    intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
2349                    startActivityLocked(null, intent, null, null, 0, aInfo,
2350                            null, null, 0, 0, 0, false, false);
2351                }
2352            }
2353            return true;
2354        }
2355
2356        next.delayedResume = false;
2357
2358        // If the top activity is the resumed one, nothing to do.
2359        if (mResumedActivity == next && next.state == ActivityState.RESUMED) {
2360            // Make sure we have executed any pending transitions, since there
2361            // should be nothing left to do at this point.
2362            mWindowManager.executeAppTransition();
2363            return false;
2364        }
2365
2366        // If we are sleeping, and there is no resumed activity, and the top
2367        // activity is paused, well that is the state we want.
2368        if ((mSleeping || mShuttingDown)
2369                && mLastPausedActivity == next && next.state == ActivityState.PAUSED) {
2370            // Make sure we have executed any pending transitions, since there
2371            // should be nothing left to do at this point.
2372            mWindowManager.executeAppTransition();
2373            return false;
2374        }
2375
2376        // The activity may be waiting for stop, but that is no longer
2377        // appropriate for it.
2378        mStoppingActivities.remove(next);
2379        mWaitingVisibleActivities.remove(next);
2380
2381        if (DEBUG_SWITCH) Log.v(TAG, "Resuming " + next);
2382
2383        // If we are currently pausing an activity, then don't do anything
2384        // until that is done.
2385        if (mPausingActivity != null) {
2386            if (DEBUG_SWITCH) Log.v(TAG, "Skip resume: pausing=" + mPausingActivity);
2387            return false;
2388        }
2389
2390        // We need to start pausing the current activity so the top one
2391        // can be resumed...
2392        if (mResumedActivity != null) {
2393            if (DEBUG_SWITCH) Log.v(TAG, "Skip resume: need to start pausing");
2394            startPausingLocked(userLeaving, false);
2395            return true;
2396        }
2397
2398        if (prev != null && prev != next) {
2399            if (!prev.waitingVisible && next != null && !next.nowVisible) {
2400                prev.waitingVisible = true;
2401                mWaitingVisibleActivities.add(prev);
2402                if (DEBUG_SWITCH) Log.v(
2403                        TAG, "Resuming top, waiting visible to hide: " + prev);
2404            } else {
2405                // The next activity is already visible, so hide the previous
2406                // activity's windows right now so we can show the new one ASAP.
2407                // We only do this if the previous is finishing, which should mean
2408                // it is on top of the one being resumed so hiding it quickly
2409                // is good.  Otherwise, we want to do the normal route of allowing
2410                // the resumed activity to be shown so we can decide if the
2411                // previous should actually be hidden depending on whether the
2412                // new one is found to be full-screen or not.
2413                if (prev.finishing) {
2414                    mWindowManager.setAppVisibility(prev, false);
2415                    if (DEBUG_SWITCH) Log.v(TAG, "Not waiting for visible to hide: "
2416                            + prev + ", waitingVisible="
2417                            + (prev != null ? prev.waitingVisible : null)
2418                            + ", nowVisible=" + next.nowVisible);
2419                } else {
2420                    if (DEBUG_SWITCH) Log.v(TAG, "Previous already visible but still waiting to hide: "
2421                        + prev + ", waitingVisible="
2422                        + (prev != null ? prev.waitingVisible : null)
2423                        + ", nowVisible=" + next.nowVisible);
2424                }
2425            }
2426        }
2427
2428        // We are starting up the next activity, so tell the window manager
2429        // that the previous one will be hidden soon.  This way it can know
2430        // to ignore it when computing the desired screen orientation.
2431        if (prev != null) {
2432            if (prev.finishing) {
2433                if (DEBUG_TRANSITION) Log.v(TAG,
2434                        "Prepare close transition: prev=" + prev);
2435                mWindowManager.prepareAppTransition(prev.task == next.task
2436                        ? WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE
2437                        : WindowManagerPolicy.TRANSIT_TASK_CLOSE);
2438                mWindowManager.setAppWillBeHidden(prev);
2439                mWindowManager.setAppVisibility(prev, false);
2440            } else {
2441                if (DEBUG_TRANSITION) Log.v(TAG,
2442                        "Prepare open transition: prev=" + prev);
2443                mWindowManager.prepareAppTransition(prev.task == next.task
2444                        ? WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
2445                        : WindowManagerPolicy.TRANSIT_TASK_OPEN);
2446            }
2447            if (false) {
2448                mWindowManager.setAppWillBeHidden(prev);
2449                mWindowManager.setAppVisibility(prev, false);
2450            }
2451        } else if (mHistory.size() > 1) {
2452            if (DEBUG_TRANSITION) Log.v(TAG,
2453                    "Prepare open transition: no previous");
2454            mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN);
2455        }
2456
2457        if (next.app != null && next.app.thread != null) {
2458            if (DEBUG_SWITCH) Log.v(TAG, "Resume running: " + next);
2459
2460            // This activity is now becoming visible.
2461            mWindowManager.setAppVisibility(next, true);
2462
2463            HistoryRecord lastResumedActivity = mResumedActivity;
2464            ActivityState lastState = next.state;
2465
2466            updateCpuStats();
2467
2468            next.state = ActivityState.RESUMED;
2469            mResumedActivity = next;
2470            next.task.touchActiveTime();
2471            updateLRUListLocked(next.app, true);
2472            updateLRUListLocked(next);
2473
2474            // Have the window manager re-evaluate the orientation of
2475            // the screen based on the new activity order.
2476            Configuration config = mWindowManager.updateOrientationFromAppTokens(
2477                    mConfiguration,
2478                    next.mayFreezeScreenLocked(next.app) ? next : null);
2479            if (config != null) {
2480                next.frozenBeforeDestroy = true;
2481            }
2482            if (!updateConfigurationLocked(config, next)) {
2483                // The configuration update wasn't able to keep the existing
2484                // instance of the activity, and instead started a new one.
2485                // We should be all done, but let's just make sure our activity
2486                // is still at the top and schedule another run if something
2487                // weird happened.
2488                HistoryRecord nextNext = topRunningActivityLocked(null);
2489                if (DEBUG_SWITCH) Log.i(TAG,
2490                        "Activity config changed during resume: " + next
2491                        + ", new next: " + nextNext);
2492                if (nextNext != next) {
2493                    // Do over!
2494                    mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG);
2495                }
2496                mWindowManager.executeAppTransition();
2497                return true;
2498            }
2499
2500            try {
2501                // Deliver all pending results.
2502                ArrayList a = next.results;
2503                if (a != null) {
2504                    final int N = a.size();
2505                    if (!next.finishing && N > 0) {
2506                        if (DEBUG_RESULTS) Log.v(
2507                                TAG, "Delivering results to " + next
2508                                + ": " + a);
2509                        next.app.thread.scheduleSendResult(next, a);
2510                    }
2511                }
2512
2513                if (next.newIntents != null) {
2514                    next.app.thread.scheduleNewIntent(next.newIntents, next);
2515                }
2516
2517                EventLog.writeEvent(LOG_AM_RESUME_ACTIVITY,
2518                        System.identityHashCode(next),
2519                        next.task.taskId, next.shortComponentName);
2520                updateUsageStats(next, true);
2521
2522                next.app.thread.scheduleResumeActivity(next,
2523                        isNextTransitionForward());
2524                pauseIfSleepingLocked();
2525
2526            } catch (Exception e) {
2527                // Whoops, need to restart this activity!
2528                next.state = lastState;
2529                mResumedActivity = lastResumedActivity;
2530                if (Config.LOGD) Log.d(TAG,
2531                        "Restarting because process died: " + next);
2532                if (!next.hasBeenLaunched) {
2533                    next.hasBeenLaunched = true;
2534                } else {
2535                    if (SHOW_APP_STARTING_ICON) {
2536                        mWindowManager.setAppStartingWindow(
2537                                next, next.packageName, next.theme,
2538                                next.nonLocalizedLabel,
2539                                next.labelRes, next.icon, null, true);
2540                    }
2541                }
2542                startSpecificActivityLocked(next, true, false);
2543                return true;
2544            }
2545
2546            // From this point on, if something goes wrong there is no way
2547            // to recover the activity.
2548            try {
2549                next.visible = true;
2550                completeResumeLocked(next);
2551            } catch (Exception e) {
2552                // If any exception gets thrown, toss away this
2553                // activity and try the next one.
2554                Log.w(TAG, "Exception thrown during resume of " + next, e);
2555                requestFinishActivityLocked(next, Activity.RESULT_CANCELED, null,
2556                        "resume-exception");
2557                return true;
2558            }
2559
2560            // Didn't need to use the icicle, and it is now out of date.
2561            next.icicle = null;
2562            next.haveState = false;
2563            next.stopped = false;
2564
2565        } else {
2566            // Whoops, need to restart this activity!
2567            if (!next.hasBeenLaunched) {
2568                next.hasBeenLaunched = true;
2569            } else {
2570                if (SHOW_APP_STARTING_ICON) {
2571                    mWindowManager.setAppStartingWindow(
2572                            next, next.packageName, next.theme,
2573                            next.nonLocalizedLabel,
2574                            next.labelRes, next.icon, null, true);
2575                }
2576                if (DEBUG_SWITCH) Log.v(TAG, "Restarting: " + next);
2577            }
2578            startSpecificActivityLocked(next, true, true);
2579        }
2580
2581        return true;
2582    }
2583
2584    private final void startActivityLocked(HistoryRecord r, boolean newTask,
2585            boolean doResume) {
2586        final int NH = mHistory.size();
2587
2588        int addPos = -1;
2589
2590        if (!newTask) {
2591            // If starting in an existing task, find where that is...
2592            HistoryRecord next = null;
2593            boolean startIt = true;
2594            for (int i = NH-1; i >= 0; i--) {
2595                HistoryRecord p = (HistoryRecord)mHistory.get(i);
2596                if (p.finishing) {
2597                    continue;
2598                }
2599                if (p.task == r.task) {
2600                    // Here it is!  Now, if this is not yet visible to the
2601                    // user, then just add it without starting; it will
2602                    // get started when the user navigates back to it.
2603                    addPos = i+1;
2604                    if (!startIt) {
2605                        mHistory.add(addPos, r);
2606                        r.inHistory = true;
2607                        r.task.numActivities++;
2608                        mWindowManager.addAppToken(addPos, r, r.task.taskId,
2609                                r.info.screenOrientation, r.fullscreen);
2610                        if (VALIDATE_TOKENS) {
2611                            mWindowManager.validateAppTokens(mHistory);
2612                        }
2613                        return;
2614                    }
2615                    break;
2616                }
2617                if (p.fullscreen) {
2618                    startIt = false;
2619                }
2620                next = p;
2621            }
2622        }
2623
2624        // Place a new activity at top of stack, so it is next to interact
2625        // with the user.
2626        if (addPos < 0) {
2627            addPos = mHistory.size();
2628        }
2629
2630        // If we are not placing the new activity frontmost, we do not want
2631        // to deliver the onUserLeaving callback to the actual frontmost
2632        // activity
2633        if (addPos < NH) {
2634            mUserLeaving = false;
2635            if (DEBUG_USER_LEAVING) Log.v(TAG, "startActivity() behind front, mUserLeaving=false");
2636        }
2637
2638        // Slot the activity into the history stack and proceed
2639        mHistory.add(addPos, r);
2640        r.inHistory = true;
2641        r.frontOfTask = newTask;
2642        r.task.numActivities++;
2643        if (NH > 0) {
2644            // We want to show the starting preview window if we are
2645            // switching to a new task, or the next activity's process is
2646            // not currently running.
2647            boolean showStartingIcon = newTask;
2648            ProcessRecord proc = r.app;
2649            if (proc == null) {
2650                proc = mProcessNames.get(r.processName, r.info.applicationInfo.uid);
2651            }
2652            if (proc == null || proc.thread == null) {
2653                showStartingIcon = true;
2654            }
2655            if (DEBUG_TRANSITION) Log.v(TAG,
2656                    "Prepare open transition: starting " + r);
2657            mWindowManager.prepareAppTransition(newTask
2658                    ? WindowManagerPolicy.TRANSIT_TASK_OPEN
2659                    : WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN);
2660            mWindowManager.addAppToken(
2661                    addPos, r, r.task.taskId, r.info.screenOrientation, r.fullscreen);
2662            boolean doShow = true;
2663            if (newTask) {
2664                // Even though this activity is starting fresh, we still need
2665                // to reset it to make sure we apply affinities to move any
2666                // existing activities from other tasks in to it.
2667                // If the caller has requested that the target task be
2668                // reset, then do so.
2669                if ((r.intent.getFlags()
2670                        &Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
2671                    resetTaskIfNeededLocked(r, r);
2672                    doShow = topRunningNonDelayedActivityLocked(null) == r;
2673                }
2674            }
2675            if (SHOW_APP_STARTING_ICON && doShow) {
2676                // Figure out if we are transitioning from another activity that is
2677                // "has the same starting icon" as the next one.  This allows the
2678                // window manager to keep the previous window it had previously
2679                // created, if it still had one.
2680                HistoryRecord prev = mResumedActivity;
2681                if (prev != null) {
2682                    // We don't want to reuse the previous starting preview if:
2683                    // (1) The current activity is in a different task.
2684                    if (prev.task != r.task) prev = null;
2685                    // (2) The current activity is already displayed.
2686                    else if (prev.nowVisible) prev = null;
2687                }
2688                mWindowManager.setAppStartingWindow(
2689                        r, r.packageName, r.theme, r.nonLocalizedLabel,
2690                        r.labelRes, r.icon, prev, showStartingIcon);
2691            }
2692        } else {
2693            // If this is the first activity, don't do any fancy animations,
2694            // because there is nothing for it to animate on top of.
2695            mWindowManager.addAppToken(addPos, r, r.task.taskId,
2696                    r.info.screenOrientation, r.fullscreen);
2697        }
2698        if (VALIDATE_TOKENS) {
2699            mWindowManager.validateAppTokens(mHistory);
2700        }
2701
2702        if (doResume) {
2703            resumeTopActivityLocked(null);
2704        }
2705    }
2706
2707    /**
2708     * Perform clear operation as requested by
2709     * {@link Intent#FLAG_ACTIVITY_CLEAR_TOP}: search from the top of the
2710     * stack to the given task, then look for
2711     * an instance of that activity in the stack and, if found, finish all
2712     * activities on top of it and return the instance.
2713     *
2714     * @param newR Description of the new activity being started.
2715     * @return Returns the old activity that should be continue to be used,
2716     * or null if none was found.
2717     */
2718    private final HistoryRecord performClearTaskLocked(int taskId,
2719            HistoryRecord newR, boolean doClear) {
2720        int i = mHistory.size();
2721
2722        // First find the requested task.
2723        while (i > 0) {
2724            i--;
2725            HistoryRecord r = (HistoryRecord)mHistory.get(i);
2726            if (r.task.taskId == taskId) {
2727                i++;
2728                break;
2729            }
2730        }
2731
2732        // Now clear it.
2733        while (i > 0) {
2734            i--;
2735            HistoryRecord r = (HistoryRecord)mHistory.get(i);
2736            if (r.finishing) {
2737                continue;
2738            }
2739            if (r.task.taskId != taskId) {
2740                return null;
2741            }
2742            if (r.realActivity.equals(newR.realActivity)) {
2743                // Here it is!  Now finish everything in front...
2744                HistoryRecord ret = r;
2745                if (doClear) {
2746                    while (i < (mHistory.size()-1)) {
2747                        i++;
2748                        r = (HistoryRecord)mHistory.get(i);
2749                        if (r.finishing) {
2750                            continue;
2751                        }
2752                        if (finishActivityLocked(r, i, Activity.RESULT_CANCELED,
2753                                null, "clear")) {
2754                            i--;
2755                        }
2756                    }
2757                }
2758
2759                // Finally, if this is a normal launch mode (that is, not
2760                // expecting onNewIntent()), then we will finish the current
2761                // instance of the activity so a new fresh one can be started.
2762                if (ret.launchMode == ActivityInfo.LAUNCH_MULTIPLE) {
2763                    if (!ret.finishing) {
2764                        int index = indexOfTokenLocked(ret, false);
2765                        if (index >= 0) {
2766                            finishActivityLocked(ret, 0, Activity.RESULT_CANCELED,
2767                                    null, "clear");
2768                        }
2769                        return null;
2770                    }
2771                }
2772
2773                return ret;
2774            }
2775        }
2776
2777        return null;
2778    }
2779
2780    /**
2781     * Find the activity in the history stack within the given task.  Returns
2782     * the index within the history at which it's found, or < 0 if not found.
2783     */
2784    private final int findActivityInHistoryLocked(HistoryRecord r, int task) {
2785        int i = mHistory.size();
2786        while (i > 0) {
2787            i--;
2788            HistoryRecord candidate = (HistoryRecord)mHistory.get(i);
2789            if (candidate.task.taskId != task) {
2790                break;
2791            }
2792            if (candidate.realActivity.equals(r.realActivity)) {
2793                return i;
2794            }
2795        }
2796
2797        return -1;
2798    }
2799
2800    /**
2801     * Reorder the history stack so that the activity at the given index is
2802     * brought to the front.
2803     */
2804    private final HistoryRecord moveActivityToFrontLocked(int where) {
2805        HistoryRecord newTop = (HistoryRecord)mHistory.remove(where);
2806        int top = mHistory.size();
2807        HistoryRecord oldTop = (HistoryRecord)mHistory.get(top-1);
2808        mHistory.add(top, newTop);
2809        oldTop.frontOfTask = false;
2810        newTop.frontOfTask = true;
2811        return newTop;
2812    }
2813
2814    /**
2815     * Deliver a new Intent to an existing activity, so that its onNewIntent()
2816     * method will be called at the proper time.
2817     */
2818    private final void deliverNewIntentLocked(HistoryRecord r, Intent intent) {
2819        boolean sent = false;
2820        if (r.state == ActivityState.RESUMED
2821                && r.app != null && r.app.thread != null) {
2822            try {
2823                ArrayList<Intent> ar = new ArrayList<Intent>();
2824                ar.add(new Intent(intent));
2825                r.app.thread.scheduleNewIntent(ar, r);
2826                sent = true;
2827            } catch (Exception e) {
2828                Log.w(TAG, "Exception thrown sending new intent to " + r, e);
2829            }
2830        }
2831        if (!sent) {
2832            r.addNewIntentLocked(new Intent(intent));
2833        }
2834    }
2835
2836    private final void logStartActivity(int tag, HistoryRecord r,
2837            TaskRecord task) {
2838        EventLog.writeEvent(tag,
2839                System.identityHashCode(r), task.taskId,
2840                r.shortComponentName, r.intent.getAction(),
2841                r.intent.getType(), r.intent.getDataString(),
2842                r.intent.getFlags());
2843    }
2844
2845    private final int startActivityLocked(IApplicationThread caller,
2846            Intent intent, String resolvedType,
2847            Uri[] grantedUriPermissions,
2848            int grantedMode, ActivityInfo aInfo, IBinder resultTo,
2849            String resultWho, int requestCode,
2850            int callingPid, int callingUid, boolean onlyIfNeeded,
2851            boolean componentSpecified) {
2852        Log.i(TAG, "Starting activity: " + intent);
2853
2854        HistoryRecord sourceRecord = null;
2855        HistoryRecord resultRecord = null;
2856        if (resultTo != null) {
2857            int index = indexOfTokenLocked(resultTo, false);
2858            if (DEBUG_RESULTS) Log.v(
2859                TAG, "Sending result to " + resultTo + " (index " + index + ")");
2860            if (index >= 0) {
2861                sourceRecord = (HistoryRecord)mHistory.get(index);
2862                if (requestCode >= 0 && !sourceRecord.finishing) {
2863                    resultRecord = sourceRecord;
2864                }
2865            }
2866        }
2867
2868        int launchFlags = intent.getFlags();
2869
2870        if ((launchFlags&Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0
2871                && sourceRecord != null) {
2872            // Transfer the result target from the source activity to the new
2873            // one being started, including any failures.
2874            if (requestCode >= 0) {
2875                return START_FORWARD_AND_REQUEST_CONFLICT;
2876            }
2877            resultRecord = sourceRecord.resultTo;
2878            resultWho = sourceRecord.resultWho;
2879            requestCode = sourceRecord.requestCode;
2880            sourceRecord.resultTo = null;
2881            if (resultRecord != null) {
2882                resultRecord.removeResultsLocked(
2883                    sourceRecord, resultWho, requestCode);
2884            }
2885        }
2886
2887        int err = START_SUCCESS;
2888
2889        if (intent.getComponent() == null) {
2890            // We couldn't find a class that can handle the given Intent.
2891            // That's the end of that!
2892            err = START_INTENT_NOT_RESOLVED;
2893        }
2894
2895        if (err == START_SUCCESS && aInfo == null) {
2896            // We couldn't find the specific class specified in the Intent.
2897            // Also the end of the line.
2898            err = START_CLASS_NOT_FOUND;
2899        }
2900
2901        ProcessRecord callerApp = null;
2902        if (err == START_SUCCESS && caller != null) {
2903            callerApp = getRecordForAppLocked(caller);
2904            if (callerApp != null) {
2905                callingPid = callerApp.pid;
2906                callingUid = callerApp.info.uid;
2907            } else {
2908                Log.w(TAG, "Unable to find app for caller " + caller
2909                      + " (pid=" + callingPid + ") when starting: "
2910                      + intent.toString());
2911                err = START_PERMISSION_DENIED;
2912            }
2913        }
2914
2915        if (err != START_SUCCESS) {
2916            if (resultRecord != null) {
2917                sendActivityResultLocked(-1,
2918                    resultRecord, resultWho, requestCode,
2919                    Activity.RESULT_CANCELED, null);
2920            }
2921            return err;
2922        }
2923
2924        final int perm = checkComponentPermission(aInfo.permission, callingPid,
2925                callingUid, aInfo.exported ? -1 : aInfo.applicationInfo.uid);
2926        if (perm != PackageManager.PERMISSION_GRANTED) {
2927            if (resultRecord != null) {
2928                sendActivityResultLocked(-1,
2929                    resultRecord, resultWho, requestCode,
2930                    Activity.RESULT_CANCELED, null);
2931            }
2932            String msg = "Permission Denial: starting " + intent.toString()
2933                    + " from " + callerApp + " (pid=" + callingPid
2934                    + ", uid=" + callingUid + ")"
2935                    + " requires " + aInfo.permission;
2936            Log.w(TAG, msg);
2937            throw new SecurityException(msg);
2938        }
2939
2940        if (mWatcher != null) {
2941            boolean abort = false;
2942            try {
2943                // The Intent we give to the watcher has the extra data
2944                // stripped off, since it can contain private information.
2945                Intent watchIntent = intent.cloneFilter();
2946                abort = !mWatcher.activityStarting(watchIntent,
2947                        aInfo.applicationInfo.packageName);
2948            } catch (RemoteException e) {
2949                mWatcher = null;
2950            }
2951
2952            if (abort) {
2953                if (resultRecord != null) {
2954                    sendActivityResultLocked(-1,
2955                        resultRecord, resultWho, requestCode,
2956                        Activity.RESULT_CANCELED, null);
2957                }
2958                // We pretend to the caller that it was really started, but
2959                // they will just get a cancel result.
2960                return START_SUCCESS;
2961            }
2962        }
2963
2964        HistoryRecord r = new HistoryRecord(this, callerApp, callingUid,
2965                intent, resolvedType, aInfo, mConfiguration,
2966                resultRecord, resultWho, requestCode, componentSpecified);
2967
2968        if (mResumedActivity == null
2969                || mResumedActivity.info.applicationInfo.uid != callingUid) {
2970            if (!checkAppSwitchAllowedLocked(callingPid, callingUid, "Activity start")) {
2971                PendingActivityLaunch pal = new PendingActivityLaunch();
2972                pal.r = r;
2973                pal.sourceRecord = sourceRecord;
2974                pal.grantedUriPermissions = grantedUriPermissions;
2975                pal.grantedMode = grantedMode;
2976                pal.onlyIfNeeded = onlyIfNeeded;
2977                mPendingActivityLaunches.add(pal);
2978                return START_SWITCHES_CANCELED;
2979            }
2980        }
2981
2982        if (mDidAppSwitch) {
2983            // This is the second allowed switch since we stopped switches,
2984            // so now just generally allow switches.  Use case: user presses
2985            // home (switches disabled, switch to home, mDidAppSwitch now true);
2986            // user taps a home icon (coming from home so allowed, we hit here
2987            // and now allow anyone to switch again).
2988            mAppSwitchesAllowedTime = 0;
2989        } else {
2990            mDidAppSwitch = true;
2991        }
2992
2993        doPendingActivityLaunchesLocked(false);
2994
2995        return startActivityUncheckedLocked(r, sourceRecord,
2996                grantedUriPermissions, grantedMode, onlyIfNeeded, true);
2997    }
2998
2999    private final void doPendingActivityLaunchesLocked(boolean doResume) {
3000        final int N = mPendingActivityLaunches.size();
3001        if (N <= 0) {
3002            return;
3003        }
3004        for (int i=0; i<N; i++) {
3005            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
3006            startActivityUncheckedLocked(pal.r, pal.sourceRecord,
3007                    pal.grantedUriPermissions, pal.grantedMode, pal.onlyIfNeeded,
3008                    doResume && i == (N-1));
3009        }
3010        mPendingActivityLaunches.clear();
3011    }
3012
3013    private final int startActivityUncheckedLocked(HistoryRecord r,
3014            HistoryRecord sourceRecord, Uri[] grantedUriPermissions,
3015            int grantedMode, boolean onlyIfNeeded, boolean doResume) {
3016        final Intent intent = r.intent;
3017        final int callingUid = r.launchedFromUid;
3018
3019        int launchFlags = intent.getFlags();
3020
3021        // We'll invoke onUserLeaving before onPause only if the launching
3022        // activity did not explicitly state that this is an automated launch.
3023        mUserLeaving = (launchFlags&Intent.FLAG_ACTIVITY_NO_USER_ACTION) == 0;
3024        if (DEBUG_USER_LEAVING) Log.v(TAG,
3025                "startActivity() => mUserLeaving=" + mUserLeaving);
3026
3027        // If the caller has asked not to resume at this point, we make note
3028        // of this in the record so that we can skip it when trying to find
3029        // the top running activity.
3030        if (!doResume) {
3031            r.delayedResume = true;
3032        }
3033
3034        HistoryRecord notTop = (launchFlags&Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP)
3035                != 0 ? r : null;
3036
3037        // If the onlyIfNeeded flag is set, then we can do this if the activity
3038        // being launched is the same as the one making the call...  or, as
3039        // a special case, if we do not know the caller then we count the
3040        // current top activity as the caller.
3041        if (onlyIfNeeded) {
3042            HistoryRecord checkedCaller = sourceRecord;
3043            if (checkedCaller == null) {
3044                checkedCaller = topRunningNonDelayedActivityLocked(notTop);
3045            }
3046            if (!checkedCaller.realActivity.equals(r.realActivity)) {
3047                // Caller is not the same as launcher, so always needed.
3048                onlyIfNeeded = false;
3049            }
3050        }
3051
3052        if (grantedUriPermissions != null && callingUid > 0) {
3053            for (int i=0; i<grantedUriPermissions.length; i++) {
3054                grantUriPermissionLocked(callingUid, r.packageName,
3055                        grantedUriPermissions[i], grantedMode, r);
3056            }
3057        }
3058
3059        grantUriPermissionFromIntentLocked(callingUid, r.packageName,
3060                intent, r);
3061
3062        if (sourceRecord == null) {
3063            // This activity is not being started from another...  in this
3064            // case we -always- start a new task.
3065            if ((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
3066                Log.w(TAG, "startActivity called from non-Activity context; forcing Intent.FLAG_ACTIVITY_NEW_TASK for: "
3067                      + intent);
3068                launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
3069            }
3070        } else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
3071            // The original activity who is starting us is running as a single
3072            // instance...  this new activity it is starting must go on its
3073            // own task.
3074            launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
3075        } else if (r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE
3076                || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
3077            // The activity being started is a single instance...  it always
3078            // gets launched into its own task.
3079            launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
3080        }
3081
3082        if (r.resultTo != null && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
3083            // For whatever reason this activity is being launched into a new
3084            // task...  yet the caller has requested a result back.  Well, that
3085            // is pretty messed up, so instead immediately send back a cancel
3086            // and let the new task continue launched as normal without a
3087            // dependency on its originator.
3088            Log.w(TAG, "Activity is launching as a new task, so cancelling activity result.");
3089            sendActivityResultLocked(-1,
3090                    r.resultTo, r.resultWho, r.requestCode,
3091                Activity.RESULT_CANCELED, null);
3092            r.resultTo = null;
3093        }
3094
3095        boolean addingToTask = false;
3096        if (((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0 &&
3097                (launchFlags&Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
3098                || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
3099                || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
3100            // If bring to front is requested, and no result is requested, and
3101            // we can find a task that was started with this same
3102            // component, then instead of launching bring that one to the front.
3103            if (r.resultTo == null) {
3104                // See if there is a task to bring to the front.  If this is
3105                // a SINGLE_INSTANCE activity, there can be one and only one
3106                // instance of it in the history, and it is always in its own
3107                // unique task, so we do a special search.
3108                HistoryRecord taskTop = r.launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE
3109                        ? findTaskLocked(intent, r.info)
3110                        : findActivityLocked(intent, r.info);
3111                if (taskTop != null) {
3112                    if (taskTop.task.intent == null) {
3113                        // This task was started because of movement of
3114                        // the activity based on affinity...  now that we
3115                        // are actually launching it, we can assign the
3116                        // base intent.
3117                        taskTop.task.setIntent(intent, r.info);
3118                    }
3119                    // If the target task is not in the front, then we need
3120                    // to bring it to the front...  except...  well, with
3121                    // SINGLE_TASK_LAUNCH it's not entirely clear.  We'd like
3122                    // to have the same behavior as if a new instance was
3123                    // being started, which means not bringing it to the front
3124                    // if the caller is not itself in the front.
3125                    HistoryRecord curTop = topRunningNonDelayedActivityLocked(notTop);
3126                    if (curTop.task != taskTop.task) {
3127                        r.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
3128                        boolean callerAtFront = sourceRecord == null
3129                                || curTop.task == sourceRecord.task;
3130                        if (callerAtFront) {
3131                            // We really do want to push this one into the
3132                            // user's face, right now.
3133                            moveTaskToFrontLocked(taskTop.task);
3134                        }
3135                    }
3136                    // If the caller has requested that the target task be
3137                    // reset, then do so.
3138                    if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
3139                        taskTop = resetTaskIfNeededLocked(taskTop, r);
3140                    }
3141                    if (onlyIfNeeded) {
3142                        // We don't need to start a new activity, and
3143                        // the client said not to do anything if that
3144                        // is the case, so this is it!  And for paranoia, make
3145                        // sure we have correctly resumed the top activity.
3146                        if (doResume) {
3147                            resumeTopActivityLocked(null);
3148                        }
3149                        return START_RETURN_INTENT_TO_CALLER;
3150                    }
3151                    if ((launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0
3152                            || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
3153                            || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
3154                        // In this situation we want to remove all activities
3155                        // from the task up to the one being started.  In most
3156                        // cases this means we are resetting the task to its
3157                        // initial state.
3158                        HistoryRecord top = performClearTaskLocked(
3159                                taskTop.task.taskId, r, true);
3160                        if (top != null) {
3161                            if (top.frontOfTask) {
3162                                // Activity aliases may mean we use different
3163                                // intents for the top activity, so make sure
3164                                // the task now has the identity of the new
3165                                // intent.
3166                                top.task.setIntent(r.intent, r.info);
3167                            }
3168                            logStartActivity(LOG_AM_NEW_INTENT, r, top.task);
3169                            deliverNewIntentLocked(top, r.intent);
3170                        } else {
3171                            // A special case: we need to
3172                            // start the activity because it is not currently
3173                            // running, and the caller has asked to clear the
3174                            // current task to have this activity at the top.
3175                            addingToTask = true;
3176                            // Now pretend like this activity is being started
3177                            // by the top of its task, so it is put in the
3178                            // right place.
3179                            sourceRecord = taskTop;
3180                        }
3181                    } else if (r.realActivity.equals(taskTop.task.realActivity)) {
3182                        // In this case the top activity on the task is the
3183                        // same as the one being launched, so we take that
3184                        // as a request to bring the task to the foreground.
3185                        // If the top activity in the task is the root
3186                        // activity, deliver this new intent to it if it
3187                        // desires.
3188                        if ((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
3189                                && taskTop.realActivity.equals(r.realActivity)) {
3190                            logStartActivity(LOG_AM_NEW_INTENT, r, taskTop.task);
3191                            if (taskTop.frontOfTask) {
3192                                taskTop.task.setIntent(r.intent, r.info);
3193                            }
3194                            deliverNewIntentLocked(taskTop, r.intent);
3195                        } else if (!r.intent.filterEquals(taskTop.task.intent)) {
3196                            // In this case we are launching the root activity
3197                            // of the task, but with a different intent.  We
3198                            // should start a new instance on top.
3199                            addingToTask = true;
3200                            sourceRecord = taskTop;
3201                        }
3202                    } else if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0) {
3203                        // In this case an activity is being launched in to an
3204                        // existing task, without resetting that task.  This
3205                        // is typically the situation of launching an activity
3206                        // from a notification or shortcut.  We want to place
3207                        // the new activity on top of the current task.
3208                        addingToTask = true;
3209                        sourceRecord = taskTop;
3210                    } else if (!taskTop.task.rootWasReset) {
3211                        // In this case we are launching in to an existing task
3212                        // that has not yet been started from its front door.
3213                        // The current task has been brought to the front.
3214                        // Ideally, we'd probably like to place this new task
3215                        // at the bottom of its stack, but that's a little hard
3216                        // to do with the current organization of the code so
3217                        // for now we'll just drop it.
3218                        taskTop.task.setIntent(r.intent, r.info);
3219                    }
3220                    if (!addingToTask) {
3221                        // We didn't do anything...  but it was needed (a.k.a., client
3222                        // don't use that intent!)  And for paranoia, make
3223                        // sure we have correctly resumed the top activity.
3224                        if (doResume) {
3225                            resumeTopActivityLocked(null);
3226                        }
3227                        return START_TASK_TO_FRONT;
3228                    }
3229                }
3230            }
3231        }
3232
3233        //String uri = r.intent.toURI();
3234        //Intent intent2 = new Intent(uri);
3235        //Log.i(TAG, "Given intent: " + r.intent);
3236        //Log.i(TAG, "URI is: " + uri);
3237        //Log.i(TAG, "To intent: " + intent2);
3238
3239        if (r.packageName != null) {
3240            // If the activity being launched is the same as the one currently
3241            // at the top, then we need to check if it should only be launched
3242            // once.
3243            HistoryRecord top = topRunningNonDelayedActivityLocked(notTop);
3244            if (top != null && r.resultTo == null) {
3245                if (top.realActivity.equals(r.realActivity)) {
3246                    if (top.app != null && top.app.thread != null) {
3247                        if ((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
3248                            || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP
3249                            || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
3250                            logStartActivity(LOG_AM_NEW_INTENT, top, top.task);
3251                            // For paranoia, make sure we have correctly
3252                            // resumed the top activity.
3253                            if (doResume) {
3254                                resumeTopActivityLocked(null);
3255                            }
3256                            if (onlyIfNeeded) {
3257                                // We don't need to start a new activity, and
3258                                // the client said not to do anything if that
3259                                // is the case, so this is it!
3260                                return START_RETURN_INTENT_TO_CALLER;
3261                            }
3262                            deliverNewIntentLocked(top, r.intent);
3263                            return START_DELIVERED_TO_TOP;
3264                        }
3265                    }
3266                }
3267            }
3268
3269        } else {
3270            if (r.resultTo != null) {
3271                sendActivityResultLocked(-1,
3272                        r.resultTo, r.resultWho, r.requestCode,
3273                    Activity.RESULT_CANCELED, null);
3274            }
3275            return START_CLASS_NOT_FOUND;
3276        }
3277
3278        boolean newTask = false;
3279
3280        // Should this be considered a new task?
3281        if (r.resultTo == null && !addingToTask
3282                && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
3283            // todo: should do better management of integers.
3284            mCurTask++;
3285            if (mCurTask <= 0) {
3286                mCurTask = 1;
3287            }
3288            r.task = new TaskRecord(mCurTask, r.info, intent,
3289                    (r.info.flags&ActivityInfo.FLAG_CLEAR_TASK_ON_LAUNCH) != 0);
3290            if (DEBUG_TASKS) Log.v(TAG, "Starting new activity " + r
3291                    + " in new task " + r.task);
3292            newTask = true;
3293            addRecentTask(r.task);
3294
3295        } else if (sourceRecord != null) {
3296            if (!addingToTask &&
3297                    (launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
3298                // In this case, we are adding the activity to an existing
3299                // task, but the caller has asked to clear that task if the
3300                // activity is already running.
3301                HistoryRecord top = performClearTaskLocked(
3302                        sourceRecord.task.taskId, r, true);
3303                if (top != null) {
3304                    logStartActivity(LOG_AM_NEW_INTENT, r, top.task);
3305                    deliverNewIntentLocked(top, r.intent);
3306                    // For paranoia, make sure we have correctly
3307                    // resumed the top activity.
3308                    if (doResume) {
3309                        resumeTopActivityLocked(null);
3310                    }
3311                    return START_DELIVERED_TO_TOP;
3312                }
3313            } else if (!addingToTask &&
3314                    (launchFlags&Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) {
3315                // In this case, we are launching an activity in our own task
3316                // that may already be running somewhere in the history, and
3317                // we want to shuffle it to the front of the stack if so.
3318                int where = findActivityInHistoryLocked(r, sourceRecord.task.taskId);
3319                if (where >= 0) {
3320                    HistoryRecord top = moveActivityToFrontLocked(where);
3321                    logStartActivity(LOG_AM_NEW_INTENT, r, top.task);
3322                    deliverNewIntentLocked(top, r.intent);
3323                    if (doResume) {
3324                        resumeTopActivityLocked(null);
3325                    }
3326                    return START_DELIVERED_TO_TOP;
3327                }
3328            }
3329            // An existing activity is starting this new activity, so we want
3330            // to keep the new one in the same task as the one that is starting
3331            // it.
3332            r.task = sourceRecord.task;
3333            if (DEBUG_TASKS) Log.v(TAG, "Starting new activity " + r
3334                    + " in existing task " + r.task);
3335
3336        } else {
3337            // This not being started from an existing activity, and not part
3338            // of a new task...  just put it in the top task, though these days
3339            // this case should never happen.
3340            final int N = mHistory.size();
3341            HistoryRecord prev =
3342                N > 0 ? (HistoryRecord)mHistory.get(N-1) : null;
3343            r.task = prev != null
3344                ? prev.task
3345                : new TaskRecord(mCurTask, r.info, intent,
3346                        (r.info.flags&ActivityInfo.FLAG_CLEAR_TASK_ON_LAUNCH) != 0);
3347            if (DEBUG_TASKS) Log.v(TAG, "Starting new activity " + r
3348                    + " in new guessed " + r.task);
3349        }
3350        if (newTask) {
3351            EventLog.writeEvent(LOG_AM_CREATE_TASK, r.task.taskId);
3352        }
3353        logStartActivity(LOG_AM_CREATE_ACTIVITY, r, r.task);
3354        startActivityLocked(r, newTask, doResume);
3355        return START_SUCCESS;
3356    }
3357
3358    public final int startActivity(IApplicationThread caller,
3359            Intent intent, String resolvedType, Uri[] grantedUriPermissions,
3360            int grantedMode, IBinder resultTo,
3361            String resultWho, int requestCode, boolean onlyIfNeeded,
3362            boolean debug) {
3363        // Refuse possible leaked file descriptors
3364        if (intent != null && intent.hasFileDescriptors()) {
3365            throw new IllegalArgumentException("File descriptors passed in Intent");
3366        }
3367
3368        final boolean componentSpecified = intent.getComponent() != null;
3369
3370        // Don't modify the client's object!
3371        intent = new Intent(intent);
3372
3373        // Collect information about the target of the Intent.
3374        // Must do this before locking, because resolving the intent
3375        // may require launching a process to run its content provider.
3376        ActivityInfo aInfo;
3377        try {
3378            ResolveInfo rInfo =
3379                ActivityThread.getPackageManager().resolveIntent(
3380                        intent, resolvedType,
3381                        PackageManager.MATCH_DEFAULT_ONLY
3382                        | STOCK_PM_FLAGS);
3383            aInfo = rInfo != null ? rInfo.activityInfo : null;
3384        } catch (RemoteException e) {
3385            aInfo = null;
3386        }
3387
3388        if (aInfo != null) {
3389            // Store the found target back into the intent, because now that
3390            // we have it we never want to do this again.  For example, if the
3391            // user navigates back to this point in the history, we should
3392            // always restart the exact same activity.
3393            intent.setComponent(new ComponentName(
3394                    aInfo.applicationInfo.packageName, aInfo.name));
3395
3396            // Don't debug things in the system process
3397            if (debug) {
3398                if (!aInfo.processName.equals("system")) {
3399                    setDebugApp(aInfo.processName, true, false);
3400                }
3401            }
3402        }
3403
3404        synchronized(this) {
3405            final long origId = Binder.clearCallingIdentity();
3406            int res = startActivityLocked(caller, intent, resolvedType,
3407                    grantedUriPermissions, grantedMode, aInfo,
3408                    resultTo, resultWho, requestCode, -1, -1,
3409                    onlyIfNeeded, componentSpecified);
3410            Binder.restoreCallingIdentity(origId);
3411            return res;
3412        }
3413    }
3414
3415    public boolean startNextMatchingActivity(IBinder callingActivity,
3416            Intent intent) {
3417        // Refuse possible leaked file descriptors
3418        if (intent != null && intent.hasFileDescriptors() == true) {
3419            throw new IllegalArgumentException("File descriptors passed in Intent");
3420        }
3421
3422        synchronized (this) {
3423            int index = indexOfTokenLocked(callingActivity, false);
3424            if (index < 0) {
3425                return false;
3426            }
3427            HistoryRecord r = (HistoryRecord)mHistory.get(index);
3428            if (r.app == null || r.app.thread == null) {
3429                // The caller is not running...  d'oh!
3430                return false;
3431            }
3432            intent = new Intent(intent);
3433            // The caller is not allowed to change the data.
3434            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3435            // And we are resetting to find the next component...
3436            intent.setComponent(null);
3437
3438            ActivityInfo aInfo = null;
3439            try {
3440                List<ResolveInfo> resolves =
3441                    ActivityThread.getPackageManager().queryIntentActivities(
3442                            intent, r.resolvedType,
3443                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS);
3444
3445                // Look for the original activity in the list...
3446                final int N = resolves != null ? resolves.size() : 0;
3447                for (int i=0; i<N; i++) {
3448                    ResolveInfo rInfo = resolves.get(i);
3449                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3450                            && rInfo.activityInfo.name.equals(r.info.name)) {
3451                        // We found the current one...  the next matching is
3452                        // after it.
3453                        i++;
3454                        if (i<N) {
3455                            aInfo = resolves.get(i).activityInfo;
3456                        }
3457                        break;
3458                    }
3459                }
3460            } catch (RemoteException e) {
3461            }
3462
3463            if (aInfo == null) {
3464                // Nobody who is next!
3465                return false;
3466            }
3467
3468            intent.setComponent(new ComponentName(
3469                    aInfo.applicationInfo.packageName, aInfo.name));
3470            intent.setFlags(intent.getFlags()&~(
3471                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3472                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3473                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3474                    Intent.FLAG_ACTIVITY_NEW_TASK));
3475
3476            // Okay now we need to start the new activity, replacing the
3477            // currently running activity.  This is a little tricky because
3478            // we want to start the new one as if the current one is finished,
3479            // but not finish the current one first so that there is no flicker.
3480            // And thus...
3481            final boolean wasFinishing = r.finishing;
3482            r.finishing = true;
3483
3484            // Propagate reply information over to the new activity.
3485            final HistoryRecord resultTo = r.resultTo;
3486            final String resultWho = r.resultWho;
3487            final int requestCode = r.requestCode;
3488            r.resultTo = null;
3489            if (resultTo != null) {
3490                resultTo.removeResultsLocked(r, resultWho, requestCode);
3491            }
3492
3493            final long origId = Binder.clearCallingIdentity();
3494            // XXX we are not dealing with propagating grantedUriPermissions...
3495            // those are not yet exposed to user code, so there is no need.
3496            int res = startActivityLocked(r.app.thread, intent,
3497                    r.resolvedType, null, 0, aInfo, resultTo, resultWho,
3498                    requestCode, -1, r.launchedFromUid, false, false);
3499            Binder.restoreCallingIdentity(origId);
3500
3501            r.finishing = wasFinishing;
3502            if (res != START_SUCCESS) {
3503                return false;
3504            }
3505            return true;
3506        }
3507    }
3508
3509    final int startActivityInPackage(int uid,
3510            Intent intent, String resolvedType, IBinder resultTo,
3511            String resultWho, int requestCode, boolean onlyIfNeeded) {
3512        final boolean componentSpecified = intent.getComponent() != null;
3513
3514        // Don't modify the client's object!
3515        intent = new Intent(intent);
3516
3517        // Collect information about the target of the Intent.
3518        // Must do this before locking, because resolving the intent
3519        // may require launching a process to run its content provider.
3520        ActivityInfo aInfo;
3521        try {
3522            ResolveInfo rInfo =
3523                ActivityThread.getPackageManager().resolveIntent(
3524                        intent, resolvedType,
3525                        PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS);
3526            aInfo = rInfo != null ? rInfo.activityInfo : null;
3527        } catch (RemoteException e) {
3528            aInfo = null;
3529        }
3530
3531        if (aInfo != null) {
3532            // Store the found target back into the intent, because now that
3533            // we have it we never want to do this again.  For example, if the
3534            // user navigates back to this point in the history, we should
3535            // always restart the exact same activity.
3536            intent.setComponent(new ComponentName(
3537                    aInfo.applicationInfo.packageName, aInfo.name));
3538        }
3539
3540        synchronized(this) {
3541            return startActivityLocked(null, intent, resolvedType,
3542                    null, 0, aInfo, resultTo, resultWho, requestCode, -1, uid,
3543                    onlyIfNeeded, componentSpecified);
3544        }
3545    }
3546
3547    private final void addRecentTask(TaskRecord task) {
3548        // Remove any existing entries that are the same kind of task.
3549        int N = mRecentTasks.size();
3550        for (int i=0; i<N; i++) {
3551            TaskRecord tr = mRecentTasks.get(i);
3552            if ((task.affinity != null && task.affinity.equals(tr.affinity))
3553                    || (task.intent != null && task.intent.filterEquals(tr.intent))) {
3554                mRecentTasks.remove(i);
3555                i--;
3556                N--;
3557                if (task.intent == null) {
3558                    // If the new recent task we are adding is not fully
3559                    // specified, then replace it with the existing recent task.
3560                    task = tr;
3561                }
3562            }
3563        }
3564        if (N >= MAX_RECENT_TASKS) {
3565            mRecentTasks.remove(N-1);
3566        }
3567        mRecentTasks.add(0, task);
3568    }
3569
3570    public void setRequestedOrientation(IBinder token,
3571            int requestedOrientation) {
3572        synchronized (this) {
3573            int index = indexOfTokenLocked(token, false);
3574            if (index < 0) {
3575                return;
3576            }
3577            HistoryRecord r = (HistoryRecord)mHistory.get(index);
3578            final long origId = Binder.clearCallingIdentity();
3579            mWindowManager.setAppOrientation(r, requestedOrientation);
3580            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3581                    mConfiguration,
3582                    r.mayFreezeScreenLocked(r.app) ? r : null);
3583            if (config != null) {
3584                r.frozenBeforeDestroy = true;
3585                if (!updateConfigurationLocked(config, r)) {
3586                    resumeTopActivityLocked(null);
3587                }
3588            }
3589            Binder.restoreCallingIdentity(origId);
3590        }
3591    }
3592
3593    public int getRequestedOrientation(IBinder token) {
3594        synchronized (this) {
3595            int index = indexOfTokenLocked(token, false);
3596            if (index < 0) {
3597                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3598            }
3599            HistoryRecord r = (HistoryRecord)mHistory.get(index);
3600            return mWindowManager.getAppOrientation(r);
3601        }
3602    }
3603
3604    private final void stopActivityLocked(HistoryRecord r) {
3605        if (DEBUG_SWITCH) Log.d(TAG, "Stopping: " + r);
3606        if ((r.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_HISTORY) != 0
3607                || (r.info.flags&ActivityInfo.FLAG_NO_HISTORY) != 0) {
3608            if (!r.finishing) {
3609                requestFinishActivityLocked(r, Activity.RESULT_CANCELED, null,
3610                        "no-history");
3611            }
3612        } else if (r.app != null && r.app.thread != null) {
3613            if (mFocusedActivity == r) {
3614                setFocusedActivityLocked(topRunningActivityLocked(null));
3615            }
3616            r.resumeKeyDispatchingLocked();
3617            try {
3618                r.stopped = false;
3619                r.state = ActivityState.STOPPING;
3620                if (DEBUG_VISBILITY) Log.v(
3621                        TAG, "Stopping visible=" + r.visible + " for " + r);
3622                if (!r.visible) {
3623                    mWindowManager.setAppVisibility(r, false);
3624                }
3625                r.app.thread.scheduleStopActivity(r, r.visible, r.configChangeFlags);
3626            } catch (Exception e) {
3627                // Maybe just ignore exceptions here...  if the process
3628                // has crashed, our death notification will clean things
3629                // up.
3630                Log.w(TAG, "Exception thrown during pause", e);
3631                // Just in case, assume it to be stopped.
3632                r.stopped = true;
3633                r.state = ActivityState.STOPPED;
3634                if (r.configDestroy) {
3635                    destroyActivityLocked(r, true);
3636                }
3637            }
3638        }
3639    }
3640
3641    /**
3642     * @return Returns true if the activity is being finished, false if for
3643     * some reason it is being left as-is.
3644     */
3645    private final boolean requestFinishActivityLocked(IBinder token, int resultCode,
3646            Intent resultData, String reason) {
3647        if (DEBUG_RESULTS) Log.v(
3648            TAG, "Finishing activity: token=" + token
3649            + ", result=" + resultCode + ", data=" + resultData);
3650
3651        int index = indexOfTokenLocked(token, false);
3652        if (index < 0) {
3653            return false;
3654        }
3655        HistoryRecord r = (HistoryRecord)mHistory.get(index);
3656
3657        // Is this the last activity left?
3658        boolean lastActivity = true;
3659        for (int i=mHistory.size()-1; i>=0; i--) {
3660            HistoryRecord p = (HistoryRecord)mHistory.get(i);
3661            if (!p.finishing && p != r) {
3662                lastActivity = false;
3663                break;
3664            }
3665        }
3666
3667        // If this is the last activity, but it is the home activity, then
3668        // just don't finish it.
3669        if (lastActivity) {
3670            if (r.intent.hasCategory(Intent.CATEGORY_HOME)) {
3671                return false;
3672            }
3673        }
3674
3675        finishActivityLocked(r, index, resultCode, resultData, reason);
3676        return true;
3677    }
3678
3679    /**
3680     * @return Returns true if this activity has been removed from the history
3681     * list, or false if it is still in the list and will be removed later.
3682     */
3683    private final boolean finishActivityLocked(HistoryRecord r, int index,
3684            int resultCode, Intent resultData, String reason) {
3685        if (r.finishing) {
3686            Log.w(TAG, "Duplicate finish request for " + r);
3687            return false;
3688        }
3689
3690        r.finishing = true;
3691        EventLog.writeEvent(LOG_AM_FINISH_ACTIVITY,
3692                System.identityHashCode(r),
3693                r.task.taskId, r.shortComponentName, reason);
3694        r.task.numActivities--;
3695        if (r.frontOfTask && index < (mHistory.size()-1)) {
3696            HistoryRecord next = (HistoryRecord)mHistory.get(index+1);
3697            if (next.task == r.task) {
3698                next.frontOfTask = true;
3699            }
3700        }
3701
3702        r.pauseKeyDispatchingLocked();
3703        if (mFocusedActivity == r) {
3704            setFocusedActivityLocked(topRunningActivityLocked(null));
3705        }
3706
3707        // send the result
3708        HistoryRecord resultTo = r.resultTo;
3709        if (resultTo != null) {
3710            if (DEBUG_RESULTS) Log.v(TAG, "Adding result to " + resultTo
3711                    + " who=" + r.resultWho + " req=" + r.requestCode
3712                    + " res=" + resultCode + " data=" + resultData);
3713            if (r.info.applicationInfo.uid > 0) {
3714                grantUriPermissionFromIntentLocked(r.info.applicationInfo.uid,
3715                        r.packageName, resultData, r);
3716            }
3717            resultTo.addResultLocked(r, r.resultWho, r.requestCode, resultCode,
3718                                     resultData);
3719            r.resultTo = null;
3720        }
3721        else if (DEBUG_RESULTS) Log.v(TAG, "No result destination from " + r);
3722
3723        // Make sure this HistoryRecord is not holding on to other resources,
3724        // because clients have remote IPC references to this object so we
3725        // can't assume that will go away and want to avoid circular IPC refs.
3726        r.results = null;
3727        r.pendingResults = null;
3728        r.newIntents = null;
3729        r.icicle = null;
3730
3731        if (mPendingThumbnails.size() > 0) {
3732            // There are clients waiting to receive thumbnails so, in case
3733            // this is an activity that someone is waiting for, add it
3734            // to the pending list so we can correctly update the clients.
3735            mCancelledThumbnails.add(r);
3736        }
3737
3738        if (mResumedActivity == r) {
3739            boolean endTask = index <= 0
3740                    || ((HistoryRecord)mHistory.get(index-1)).task != r.task;
3741            if (DEBUG_TRANSITION) Log.v(TAG,
3742                    "Prepare close transition: finishing " + r);
3743            mWindowManager.prepareAppTransition(endTask
3744                    ? WindowManagerPolicy.TRANSIT_TASK_CLOSE
3745                    : WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE);
3746
3747            // Tell window manager to prepare for this one to be removed.
3748            mWindowManager.setAppVisibility(r, false);
3749
3750            if (mPausingActivity == null) {
3751                if (DEBUG_PAUSE) Log.v(TAG, "Finish needs to pause: " + r);
3752                if (DEBUG_USER_LEAVING) Log.v(TAG, "finish() => pause with userLeaving=false");
3753                startPausingLocked(false, false);
3754            }
3755
3756        } else if (r.state != ActivityState.PAUSING) {
3757            // If the activity is PAUSING, we will complete the finish once
3758            // it is done pausing; else we can just directly finish it here.
3759            if (DEBUG_PAUSE) Log.v(TAG, "Finish not pausing: " + r);
3760            return finishCurrentActivityLocked(r, index,
3761                    FINISH_AFTER_PAUSE) == null;
3762        } else {
3763            if (DEBUG_PAUSE) Log.v(TAG, "Finish waiting for pause of: " + r);
3764        }
3765
3766        return false;
3767    }
3768
3769    private static final int FINISH_IMMEDIATELY = 0;
3770    private static final int FINISH_AFTER_PAUSE = 1;
3771    private static final int FINISH_AFTER_VISIBLE = 2;
3772
3773    private final HistoryRecord finishCurrentActivityLocked(HistoryRecord r,
3774            int mode) {
3775        final int index = indexOfTokenLocked(r, false);
3776        if (index < 0) {
3777            return null;
3778        }
3779
3780        return finishCurrentActivityLocked(r, index, mode);
3781    }
3782
3783    private final HistoryRecord finishCurrentActivityLocked(HistoryRecord r,
3784            int index, int mode) {
3785        // First things first: if this activity is currently visible,
3786        // and the resumed activity is not yet visible, then hold off on
3787        // finishing until the resumed one becomes visible.
3788        if (mode == FINISH_AFTER_VISIBLE && r.nowVisible) {
3789            if (!mStoppingActivities.contains(r)) {
3790                mStoppingActivities.add(r);
3791                if (mStoppingActivities.size() > 3) {
3792                    // If we already have a few activities waiting to stop,
3793                    // then give up on things going idle and start clearing
3794                    // them out.
3795                    Message msg = Message.obtain();
3796                    msg.what = ActivityManagerService.IDLE_NOW_MSG;
3797                    mHandler.sendMessage(msg);
3798                }
3799            }
3800            r.state = ActivityState.STOPPING;
3801            updateOomAdjLocked();
3802            return r;
3803        }
3804
3805        // make sure the record is cleaned out of other places.
3806        mStoppingActivities.remove(r);
3807        mWaitingVisibleActivities.remove(r);
3808        if (mResumedActivity == r) {
3809            mResumedActivity = null;
3810        }
3811        final ActivityState prevState = r.state;
3812        r.state = ActivityState.FINISHING;
3813
3814        if (mode == FINISH_IMMEDIATELY
3815                || prevState == ActivityState.STOPPED
3816                || prevState == ActivityState.INITIALIZING) {
3817            // If this activity is already stopped, we can just finish
3818            // it right now.
3819            return destroyActivityLocked(r, true) ? null : r;
3820        } else {
3821            // Need to go through the full pause cycle to get this
3822            // activity into the stopped state and then finish it.
3823            if (localLOGV) Log.v(TAG, "Enqueueing pending finish: " + r);
3824            mFinishingActivities.add(r);
3825            resumeTopActivityLocked(null);
3826        }
3827        return r;
3828    }
3829
3830    /**
3831     * This is the internal entry point for handling Activity.finish().
3832     *
3833     * @param token The Binder token referencing the Activity we want to finish.
3834     * @param resultCode Result code, if any, from this Activity.
3835     * @param resultData Result data (Intent), if any, from this Activity.
3836     *
3837     * @result Returns true if the activity successfully finished, or false if it is still running.
3838     */
3839    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
3840        // Refuse possible leaked file descriptors
3841        if (resultData != null && resultData.hasFileDescriptors() == true) {
3842            throw new IllegalArgumentException("File descriptors passed in Intent");
3843        }
3844
3845        synchronized(this) {
3846            if (mWatcher != null) {
3847                // Find the first activity that is not finishing.
3848                HistoryRecord next = topRunningActivityLocked(token, 0);
3849                if (next != null) {
3850                    // ask watcher if this is allowed
3851                    boolean resumeOK = true;
3852                    try {
3853                        resumeOK = mWatcher.activityResuming(next.packageName);
3854                    } catch (RemoteException e) {
3855                        mWatcher = null;
3856                    }
3857
3858                    if (!resumeOK) {
3859                        return false;
3860                    }
3861                }
3862            }
3863            final long origId = Binder.clearCallingIdentity();
3864            boolean res = requestFinishActivityLocked(token, resultCode,
3865                    resultData, "app-request");
3866            Binder.restoreCallingIdentity(origId);
3867            return res;
3868        }
3869    }
3870
3871    void sendActivityResultLocked(int callingUid, HistoryRecord r,
3872            String resultWho, int requestCode, int resultCode, Intent data) {
3873
3874        if (callingUid > 0) {
3875            grantUriPermissionFromIntentLocked(callingUid, r.packageName,
3876                    data, r);
3877        }
3878
3879        if (DEBUG_RESULTS) Log.v(TAG, "Send activity result to " + r
3880                + " : who=" + resultWho + " req=" + requestCode
3881                + " res=" + resultCode + " data=" + data);
3882        if (mResumedActivity == r && r.app != null && r.app.thread != null) {
3883            try {
3884                ArrayList<ResultInfo> list = new ArrayList<ResultInfo>();
3885                list.add(new ResultInfo(resultWho, requestCode,
3886                        resultCode, data));
3887                r.app.thread.scheduleSendResult(r, list);
3888                return;
3889            } catch (Exception e) {
3890                Log.w(TAG, "Exception thrown sending result to " + r, e);
3891            }
3892        }
3893
3894        r.addResultLocked(null, resultWho, requestCode, resultCode, data);
3895    }
3896
3897    public final void finishSubActivity(IBinder token, String resultWho,
3898            int requestCode) {
3899        synchronized(this) {
3900            int index = indexOfTokenLocked(token, false);
3901            if (index < 0) {
3902                return;
3903            }
3904            HistoryRecord self = (HistoryRecord)mHistory.get(index);
3905
3906            final long origId = Binder.clearCallingIdentity();
3907
3908            int i;
3909            for (i=mHistory.size()-1; i>=0; i--) {
3910                HistoryRecord r = (HistoryRecord)mHistory.get(i);
3911                if (r.resultTo == self && r.requestCode == requestCode) {
3912                    if ((r.resultWho == null && resultWho == null) ||
3913                        (r.resultWho != null && r.resultWho.equals(resultWho))) {
3914                        finishActivityLocked(r, i,
3915                                Activity.RESULT_CANCELED, null, "request-sub");
3916                    }
3917                }
3918            }
3919
3920            Binder.restoreCallingIdentity(origId);
3921        }
3922    }
3923
3924    /**
3925     * Perform clean-up of service connections in an activity record.
3926     */
3927    private final void cleanUpActivityServicesLocked(HistoryRecord r) {
3928        // Throw away any services that have been bound by this activity.
3929        if (r.connections != null) {
3930            Iterator<ConnectionRecord> it = r.connections.iterator();
3931            while (it.hasNext()) {
3932                ConnectionRecord c = it.next();
3933                removeConnectionLocked(c, null, r);
3934            }
3935            r.connections = null;
3936        }
3937    }
3938
3939    /**
3940     * Perform the common clean-up of an activity record.  This is called both
3941     * as part of destroyActivityLocked() (when destroying the client-side
3942     * representation) and cleaning things up as a result of its hosting
3943     * processing going away, in which case there is no remaining client-side
3944     * state to destroy so only the cleanup here is needed.
3945     */
3946    private final void cleanUpActivityLocked(HistoryRecord r, boolean cleanServices) {
3947        if (mResumedActivity == r) {
3948            mResumedActivity = null;
3949        }
3950        if (mFocusedActivity == r) {
3951            mFocusedActivity = null;
3952        }
3953
3954        r.configDestroy = false;
3955        r.frozenBeforeDestroy = false;
3956
3957        // Make sure this record is no longer in the pending finishes list.
3958        // This could happen, for example, if we are trimming activities
3959        // down to the max limit while they are still waiting to finish.
3960        mFinishingActivities.remove(r);
3961        mWaitingVisibleActivities.remove(r);
3962
3963        // Remove any pending results.
3964        if (r.finishing && r.pendingResults != null) {
3965            for (WeakReference<PendingIntentRecord> apr : r.pendingResults) {
3966                PendingIntentRecord rec = apr.get();
3967                if (rec != null) {
3968                    cancelIntentSenderLocked(rec, false);
3969                }
3970            }
3971            r.pendingResults = null;
3972        }
3973
3974        if (cleanServices) {
3975            cleanUpActivityServicesLocked(r);
3976        }
3977
3978        if (mPendingThumbnails.size() > 0) {
3979            // There are clients waiting to receive thumbnails so, in case
3980            // this is an activity that someone is waiting for, add it
3981            // to the pending list so we can correctly update the clients.
3982            mCancelledThumbnails.add(r);
3983        }
3984
3985        // Get rid of any pending idle timeouts.
3986        mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);
3987        mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
3988    }
3989
3990    private final void removeActivityFromHistoryLocked(HistoryRecord r) {
3991        if (r.state != ActivityState.DESTROYED) {
3992            mHistory.remove(r);
3993            r.inHistory = false;
3994            r.state = ActivityState.DESTROYED;
3995            mWindowManager.removeAppToken(r);
3996            if (VALIDATE_TOKENS) {
3997                mWindowManager.validateAppTokens(mHistory);
3998            }
3999            cleanUpActivityServicesLocked(r);
4000            removeActivityUriPermissionsLocked(r);
4001        }
4002    }
4003
4004    /**
4005     * Destroy the current CLIENT SIDE instance of an activity.  This may be
4006     * called both when actually finishing an activity, or when performing
4007     * a configuration switch where we destroy the current client-side object
4008     * but then create a new client-side object for this same HistoryRecord.
4009     */
4010    private final boolean destroyActivityLocked(HistoryRecord r,
4011            boolean removeFromApp) {
4012        if (DEBUG_SWITCH) Log.v(
4013            TAG, "Removing activity: token=" + r
4014              + ", app=" + (r.app != null ? r.app.processName : "(null)"));
4015        EventLog.writeEvent(LOG_AM_DESTROY_ACTIVITY,
4016                System.identityHashCode(r),
4017                r.task.taskId, r.shortComponentName);
4018
4019        boolean removedFromHistory = false;
4020
4021        cleanUpActivityLocked(r, false);
4022
4023        if (r.app != null) {
4024            if (removeFromApp) {
4025                int idx = r.app.activities.indexOf(r);
4026                if (idx >= 0) {
4027                    r.app.activities.remove(idx);
4028                }
4029                if (r.persistent) {
4030                    decPersistentCountLocked(r.app);
4031                }
4032            }
4033
4034            boolean skipDestroy = false;
4035
4036            try {
4037                if (DEBUG_SWITCH) Log.i(TAG, "Destroying: " + r);
4038                r.app.thread.scheduleDestroyActivity(r, r.finishing,
4039                        r.configChangeFlags);
4040            } catch (Exception e) {
4041                // We can just ignore exceptions here...  if the process
4042                // has crashed, our death notification will clean things
4043                // up.
4044                //Log.w(TAG, "Exception thrown during finish", e);
4045                if (r.finishing) {
4046                    removeActivityFromHistoryLocked(r);
4047                    removedFromHistory = true;
4048                    skipDestroy = true;
4049                }
4050            }
4051
4052            r.app = null;
4053            r.nowVisible = false;
4054
4055            if (r.finishing && !skipDestroy) {
4056                r.state = ActivityState.DESTROYING;
4057                Message msg = mHandler.obtainMessage(DESTROY_TIMEOUT_MSG);
4058                msg.obj = r;
4059                mHandler.sendMessageDelayed(msg, DESTROY_TIMEOUT);
4060            } else {
4061                r.state = ActivityState.DESTROYED;
4062            }
4063        } else {
4064            // remove this record from the history.
4065            if (r.finishing) {
4066                removeActivityFromHistoryLocked(r);
4067                removedFromHistory = true;
4068            } else {
4069                r.state = ActivityState.DESTROYED;
4070            }
4071        }
4072
4073        r.configChangeFlags = 0;
4074
4075        if (!mLRUActivities.remove(r)) {
4076            Log.w(TAG, "Activity " + r + " being finished, but not in LRU list");
4077        }
4078
4079        return removedFromHistory;
4080    }
4081
4082    private static void removeHistoryRecordsForAppLocked(ArrayList list,
4083                                                         ProcessRecord app)
4084    {
4085        int i = list.size();
4086        if (localLOGV) Log.v(
4087            TAG, "Removing app " + app + " from list " + list
4088            + " with " + i + " entries");
4089        while (i > 0) {
4090            i--;
4091            HistoryRecord r = (HistoryRecord)list.get(i);
4092            if (localLOGV) Log.v(
4093                TAG, "Record #" + i + " " + r + ": app=" + r.app);
4094            if (r.app == app) {
4095                if (localLOGV) Log.v(TAG, "Removing this entry!");
4096                list.remove(i);
4097            }
4098        }
4099    }
4100
4101    /**
4102     * Main function for removing an existing process from the activity manager
4103     * as a result of that process going away.  Clears out all connections
4104     * to the process.
4105     */
4106    private final void handleAppDiedLocked(ProcessRecord app,
4107            boolean restarting) {
4108        cleanUpApplicationRecordLocked(app, restarting, -1);
4109        if (!restarting) {
4110            mLRUProcesses.remove(app);
4111        }
4112
4113        // Just in case...
4114        if (mPausingActivity != null && mPausingActivity.app == app) {
4115            if (DEBUG_PAUSE) Log.v(TAG, "App died while pausing: " + mPausingActivity);
4116            mPausingActivity = null;
4117        }
4118        if (mLastPausedActivity != null && mLastPausedActivity.app == app) {
4119            mLastPausedActivity = null;
4120        }
4121
4122        // Remove this application's activities from active lists.
4123        removeHistoryRecordsForAppLocked(mLRUActivities, app);
4124        removeHistoryRecordsForAppLocked(mStoppingActivities, app);
4125        removeHistoryRecordsForAppLocked(mWaitingVisibleActivities, app);
4126        removeHistoryRecordsForAppLocked(mFinishingActivities, app);
4127
4128        boolean atTop = true;
4129        boolean hasVisibleActivities = false;
4130
4131        // Clean out the history list.
4132        int i = mHistory.size();
4133        if (localLOGV) Log.v(
4134            TAG, "Removing app " + app + " from history with " + i + " entries");
4135        while (i > 0) {
4136            i--;
4137            HistoryRecord r = (HistoryRecord)mHistory.get(i);
4138            if (localLOGV) Log.v(
4139                TAG, "Record #" + i + " " + r + ": app=" + r.app);
4140            if (r.app == app) {
4141                if ((!r.haveState && !r.stateNotNeeded) || r.finishing) {
4142                    if (localLOGV) Log.v(
4143                        TAG, "Removing this entry!  frozen=" + r.haveState
4144                        + " finishing=" + r.finishing);
4145                    mHistory.remove(i);
4146
4147                    r.inHistory = false;
4148                    mWindowManager.removeAppToken(r);
4149                    if (VALIDATE_TOKENS) {
4150                        mWindowManager.validateAppTokens(mHistory);
4151                    }
4152                    removeActivityUriPermissionsLocked(r);
4153
4154                } else {
4155                    // We have the current state for this activity, so
4156                    // it can be restarted later when needed.
4157                    if (localLOGV) Log.v(
4158                        TAG, "Keeping entry, setting app to null");
4159                    if (r.visible) {
4160                        hasVisibleActivities = true;
4161                    }
4162                    r.app = null;
4163                    r.nowVisible = false;
4164                    if (!r.haveState) {
4165                        r.icicle = null;
4166                    }
4167                }
4168
4169                cleanUpActivityLocked(r, true);
4170                r.state = ActivityState.STOPPED;
4171            }
4172            atTop = false;
4173        }
4174
4175        app.activities.clear();
4176
4177        if (app.instrumentationClass != null) {
4178            Log.w(TAG, "Crash of app " + app.processName
4179                  + " running instrumentation " + app.instrumentationClass);
4180            Bundle info = new Bundle();
4181            info.putString("shortMsg", "Process crashed.");
4182            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4183        }
4184
4185        if (!restarting) {
4186            if (!resumeTopActivityLocked(null)) {
4187                // If there was nothing to resume, and we are not already
4188                // restarting this process, but there is a visible activity that
4189                // is hosted by the process...  then make sure all visible
4190                // activities are running, taking care of restarting this
4191                // process.
4192                if (hasVisibleActivities) {
4193                    ensureActivitiesVisibleLocked(null, 0);
4194                }
4195            }
4196        }
4197    }
4198
4199    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4200        IBinder threadBinder = thread.asBinder();
4201
4202        // Find the application record.
4203        int count = mLRUProcesses.size();
4204        int i;
4205        for (i=0; i<count; i++) {
4206            ProcessRecord rec = mLRUProcesses.get(i);
4207            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4208                return i;
4209            }
4210        }
4211        return -1;
4212    }
4213
4214    private final ProcessRecord getRecordForAppLocked(
4215            IApplicationThread thread) {
4216        if (thread == null) {
4217            return null;
4218        }
4219
4220        int appIndex = getLRURecordIndexForAppLocked(thread);
4221        return appIndex >= 0 ? mLRUProcesses.get(appIndex) : null;
4222    }
4223
4224    private final void appDiedLocked(ProcessRecord app, int pid,
4225            IApplicationThread thread) {
4226
4227        mProcDeaths[0]++;
4228
4229        if (app.thread != null && app.thread.asBinder() == thread.asBinder()) {
4230            Log.i(TAG, "Process " + app.processName + " (pid " + pid
4231                    + ") has died.");
4232            EventLog.writeEvent(LOG_AM_PROCESS_DIED, app.pid, app.processName);
4233            if (localLOGV) Log.v(
4234                TAG, "Dying app: " + app + ", pid: " + pid
4235                + ", thread: " + thread.asBinder());
4236            boolean doLowMem = app.instrumentationClass == null;
4237            handleAppDiedLocked(app, false);
4238
4239            if (doLowMem) {
4240                // If there are no longer any background processes running,
4241                // and the app that died was not running instrumentation,
4242                // then tell everyone we are now low on memory.
4243                boolean haveBg = false;
4244                int count = mLRUProcesses.size();
4245                int i;
4246                for (i=0; i<count; i++) {
4247                    ProcessRecord rec = mLRUProcesses.get(i);
4248                    if (rec.thread != null && rec.setAdj >= HIDDEN_APP_MIN_ADJ) {
4249                        haveBg = true;
4250                        break;
4251                    }
4252                }
4253
4254                if (!haveBg) {
4255                    Log.i(TAG, "Low Memory: No more background processes.");
4256                    EventLog.writeEvent(LOG_AM_LOW_MEMORY, mLRUProcesses.size());
4257                    for (i=0; i<count; i++) {
4258                        ProcessRecord rec = mLRUProcesses.get(i);
4259                        if (rec.thread != null) {
4260                            rec.lastRequestedGc = SystemClock.uptimeMillis();
4261                            try {
4262                                rec.thread.scheduleLowMemory();
4263                            } catch (RemoteException e) {
4264                                // Don't care if the process is gone.
4265                            }
4266                        }
4267                    }
4268                }
4269            }
4270        } else if (Config.LOGD) {
4271            Log.d(TAG, "Received spurious death notification for thread "
4272                    + thread.asBinder());
4273        }
4274    }
4275
4276    final String readFile(String filename) {
4277        try {
4278            FileInputStream fs = new FileInputStream(filename);
4279            byte[] inp = new byte[8192];
4280            int size = fs.read(inp);
4281            fs.close();
4282            return new String(inp, 0, 0, size);
4283        } catch (java.io.IOException e) {
4284        }
4285        return "";
4286    }
4287
4288    final void appNotRespondingLocked(ProcessRecord app, HistoryRecord activity,
4289            final String annotation) {
4290        if (app.notResponding || app.crashing) {
4291            return;
4292        }
4293
4294        // Log the ANR to the event log.
4295        EventLog.writeEvent(LOG_ANR, app.pid, app.processName, annotation);
4296
4297        // If we are on a secure build and the application is not interesting to the user (it is
4298        // not visible or in the background), just kill it instead of displaying a dialog.
4299        boolean isSecure = "1".equals(SystemProperties.get(SYSTEM_SECURE, "0"));
4300        if (isSecure && !app.isInterestingToUserLocked() && Process.myPid() != app.pid) {
4301            Process.killProcess(app.pid);
4302            return;
4303        }
4304
4305        // DeviceMonitor.start();
4306
4307        String processInfo = null;
4308        if (MONITOR_CPU_USAGE) {
4309            updateCpuStatsNow();
4310            synchronized (mProcessStatsThread) {
4311                processInfo = mProcessStats.printCurrentState();
4312            }
4313        }
4314
4315        StringBuilder info = mStringBuilder;
4316        info.setLength(0);
4317        info.append("ANR (application not responding) in process: ");
4318        info.append(app.processName);
4319        if (annotation != null) {
4320            info.append("\nAnnotation: ");
4321            info.append(annotation);
4322        }
4323        if (MONITOR_CPU_USAGE) {
4324            info.append("\nCPU usage:\n");
4325            info.append(processInfo);
4326        }
4327        Log.i(TAG, info.toString());
4328
4329        // The application is not responding. Dump as many thread traces as we can.
4330        boolean fileDump = prepareTraceFile(true);
4331        if (!fileDump) {
4332            // Dumping traces to the log, just dump the process that isn't responding so
4333            // we don't overflow the log
4334            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4335        } else {
4336            // Dumping traces to a file so dump all active processes we know about
4337            synchronized (this) {
4338                for (int i = mLRUProcesses.size() - 1 ; i >= 0 ; i--) {
4339                    ProcessRecord r = mLRUProcesses.get(i);
4340                    if (r.thread != null) {
4341                        Process.sendSignal(r.pid, Process.SIGNAL_QUIT);
4342                    }
4343                }
4344            }
4345        }
4346
4347        if (mWatcher != null) {
4348            try {
4349                int res = mWatcher.appNotResponding(app.processName,
4350                        app.pid, info.toString());
4351                if (res != 0) {
4352                    if (res < 0) {
4353                        // wait until the SIGQUIT has had a chance to process before killing the
4354                        // process.
4355                        try {
4356                            wait(2000);
4357                        } catch (InterruptedException e) {
4358                        }
4359
4360                        Process.killProcess(app.pid);
4361                        return;
4362                    }
4363                }
4364            } catch (RemoteException e) {
4365                mWatcher = null;
4366            }
4367        }
4368
4369        makeAppNotRespondingLocked(app,
4370                activity != null ? activity.shortComponentName : null,
4371                annotation != null ? "ANR " + annotation : "ANR",
4372                info.toString(), null);
4373        Message msg = Message.obtain();
4374        HashMap map = new HashMap();
4375        msg.what = SHOW_NOT_RESPONDING_MSG;
4376        msg.obj = map;
4377        map.put("app", app);
4378        if (activity != null) {
4379            map.put("activity", activity);
4380        }
4381
4382        mHandler.sendMessage(msg);
4383        return;
4384    }
4385
4386    /**
4387     * If a stack trace file has been configured, prepare the filesystem
4388     * by creating the directory if it doesn't exist and optionally
4389     * removing the old trace file.
4390     *
4391     * @param removeExisting If set, the existing trace file will be removed.
4392     * @return Returns true if the trace file preparations succeeded
4393     */
4394    public static boolean prepareTraceFile(boolean removeExisting) {
4395        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4396        boolean fileReady = false;
4397        if (!TextUtils.isEmpty(tracesPath)) {
4398            File f = new File(tracesPath);
4399            if (!f.exists()) {
4400                // Ensure the enclosing directory exists
4401                File dir = f.getParentFile();
4402                if (!dir.exists()) {
4403                    fileReady = dir.mkdirs();
4404                    FileUtils.setPermissions(dir.getAbsolutePath(),
4405                            FileUtils.S_IRWXU | FileUtils.S_IRWXG | FileUtils.S_IRWXO, -1, -1);
4406                } else if (dir.isDirectory()) {
4407                    fileReady = true;
4408                }
4409            } else if (removeExisting) {
4410                // Remove the previous traces file, so we don't fill the disk.
4411                // The VM will recreate it
4412                Log.i(TAG, "Removing old ANR trace file from " + tracesPath);
4413                fileReady = f.delete();
4414            }
4415        }
4416
4417        return fileReady;
4418    }
4419
4420
4421    private final void decPersistentCountLocked(ProcessRecord app)
4422    {
4423        app.persistentActivities--;
4424        if (app.persistentActivities > 0) {
4425            // Still more of 'em...
4426            return;
4427        }
4428        if (app.persistent) {
4429            // Ah, but the application itself is persistent.  Whatever!
4430            return;
4431        }
4432
4433        // App is no longer persistent...  make sure it and the ones
4434        // following it in the LRU list have the correc oom_adj.
4435        updateOomAdjLocked();
4436    }
4437
4438    public void setPersistent(IBinder token, boolean isPersistent) {
4439        if (checkCallingPermission(android.Manifest.permission.PERSISTENT_ACTIVITY)
4440                != PackageManager.PERMISSION_GRANTED) {
4441            String msg = "Permission Denial: setPersistent() from pid="
4442                    + Binder.getCallingPid()
4443                    + ", uid=" + Binder.getCallingUid()
4444                    + " requires " + android.Manifest.permission.PERSISTENT_ACTIVITY;
4445            Log.w(TAG, msg);
4446            throw new SecurityException(msg);
4447        }
4448
4449        synchronized(this) {
4450            int index = indexOfTokenLocked(token, true);
4451            if (index < 0) {
4452                return;
4453            }
4454            HistoryRecord r = (HistoryRecord)mHistory.get(index);
4455            ProcessRecord app = r.app;
4456
4457            if (localLOGV) Log.v(
4458                TAG, "Setting persistence " + isPersistent + ": " + r);
4459
4460            if (isPersistent) {
4461                if (r.persistent) {
4462                    // Okay okay, I heard you already!
4463                    if (localLOGV) Log.v(TAG, "Already persistent!");
4464                    return;
4465                }
4466                r.persistent = true;
4467                app.persistentActivities++;
4468                if (localLOGV) Log.v(TAG, "Num persistent now: " + app.persistentActivities);
4469                if (app.persistentActivities > 1) {
4470                    // We aren't the first...
4471                    if (localLOGV) Log.v(TAG, "Not the first!");
4472                    return;
4473                }
4474                if (app.persistent) {
4475                    // This would be redundant.
4476                    if (localLOGV) Log.v(TAG, "App is persistent!");
4477                    return;
4478                }
4479
4480                // App is now persistent...  make sure it and the ones
4481                // following it now have the correct oom_adj.
4482                final long origId = Binder.clearCallingIdentity();
4483                updateOomAdjLocked();
4484                Binder.restoreCallingIdentity(origId);
4485
4486            } else {
4487                if (!r.persistent) {
4488                    // Okay okay, I heard you already!
4489                    return;
4490                }
4491                r.persistent = false;
4492                final long origId = Binder.clearCallingIdentity();
4493                decPersistentCountLocked(app);
4494                Binder.restoreCallingIdentity(origId);
4495
4496            }
4497        }
4498    }
4499
4500    public boolean clearApplicationUserData(final String packageName,
4501            final IPackageDataObserver observer) {
4502        int uid = Binder.getCallingUid();
4503        int pid = Binder.getCallingPid();
4504        long callingId = Binder.clearCallingIdentity();
4505        try {
4506            IPackageManager pm = ActivityThread.getPackageManager();
4507            int pkgUid = -1;
4508            synchronized(this) {
4509                try {
4510                    pkgUid = pm.getPackageUid(packageName);
4511                } catch (RemoteException e) {
4512                }
4513                if (pkgUid == -1) {
4514                    Log.w(TAG, "Invalid packageName:" + packageName);
4515                    return false;
4516                }
4517                if (uid == pkgUid || checkComponentPermission(
4518                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4519                        pid, uid, -1)
4520                        == PackageManager.PERMISSION_GRANTED) {
4521                    restartPackageLocked(packageName, pkgUid);
4522                } else {
4523                    throw new SecurityException(pid+" does not have permission:"+
4524                            android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" +
4525                                    "for process:"+packageName);
4526                }
4527            }
4528
4529            try {
4530                //clear application user data
4531                pm.clearApplicationUserData(packageName, observer);
4532                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4533                        Uri.fromParts("package", packageName, null));
4534                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4535                broadcastIntentLocked(null, null, intent,
4536                        null, null, 0, null, null, null,
4537                        false, false, MY_PID, Process.SYSTEM_UID);
4538            } catch (RemoteException e) {
4539            }
4540        } finally {
4541            Binder.restoreCallingIdentity(callingId);
4542        }
4543        return true;
4544    }
4545
4546    public void restartPackage(final String packageName) {
4547        if (checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4548                != PackageManager.PERMISSION_GRANTED) {
4549            String msg = "Permission Denial: restartPackage() from pid="
4550                    + Binder.getCallingPid()
4551                    + ", uid=" + Binder.getCallingUid()
4552                    + " requires " + android.Manifest.permission.RESTART_PACKAGES;
4553            Log.w(TAG, msg);
4554            throw new SecurityException(msg);
4555        }
4556
4557        long callingId = Binder.clearCallingIdentity();
4558        try {
4559            IPackageManager pm = ActivityThread.getPackageManager();
4560            int pkgUid = -1;
4561            synchronized(this) {
4562                try {
4563                    pkgUid = pm.getPackageUid(packageName);
4564                } catch (RemoteException e) {
4565                }
4566                if (pkgUid == -1) {
4567                    Log.w(TAG, "Invalid packageName: " + packageName);
4568                    return;
4569                }
4570                restartPackageLocked(packageName, pkgUid);
4571            }
4572        } finally {
4573            Binder.restoreCallingIdentity(callingId);
4574        }
4575    }
4576
4577    private void restartPackageLocked(final String packageName, int uid) {
4578        uninstallPackageLocked(packageName, uid, false);
4579        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4580                Uri.fromParts("package", packageName, null));
4581        intent.putExtra(Intent.EXTRA_UID, uid);
4582        broadcastIntentLocked(null, null, intent,
4583                null, null, 0, null, null, null,
4584                false, false, MY_PID, Process.SYSTEM_UID);
4585    }
4586
4587    private final void uninstallPackageLocked(String name, int uid,
4588            boolean callerWillRestart) {
4589        if (Config.LOGD) Log.d(TAG, "Uninstalling process " + name);
4590
4591        int i, N;
4592
4593        final String procNamePrefix = name + ":";
4594        if (uid < 0) {
4595            try {
4596                uid = ActivityThread.getPackageManager().getPackageUid(name);
4597            } catch (RemoteException e) {
4598            }
4599        }
4600
4601        Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator();
4602        while (badApps.hasNext()) {
4603            SparseArray<Long> ba = badApps.next();
4604            if (ba.get(uid) != null) {
4605                badApps.remove();
4606            }
4607        }
4608
4609        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4610
4611        // Remove all processes this package may have touched: all with the
4612        // same UID (except for the system or root user), and all whose name
4613        // matches the package name.
4614        for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
4615            final int NA = apps.size();
4616            for (int ia=0; ia<NA; ia++) {
4617                ProcessRecord app = apps.valueAt(ia);
4618                if (app.removed) {
4619                    procs.add(app);
4620                } else if ((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid)
4621                        || app.processName.equals(name)
4622                        || app.processName.startsWith(procNamePrefix)) {
4623                    app.removed = true;
4624                    procs.add(app);
4625                }
4626            }
4627        }
4628
4629        N = procs.size();
4630        for (i=0; i<N; i++) {
4631            removeProcessLocked(procs.get(i), callerWillRestart);
4632        }
4633
4634        for (i=mHistory.size()-1; i>=0; i--) {
4635            HistoryRecord r = (HistoryRecord)mHistory.get(i);
4636            if (r.packageName.equals(name)) {
4637                if (Config.LOGD) Log.d(
4638                    TAG, "  Force finishing activity "
4639                    + r.intent.getComponent().flattenToShortString());
4640                if (r.app != null) {
4641                    r.app.removed = true;
4642                }
4643                r.app = null;
4644                finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "uninstall");
4645            }
4646        }
4647
4648        ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
4649        for (ServiceRecord service : mServices.values()) {
4650            if (service.packageName.equals(name)) {
4651                if (service.app != null) {
4652                    service.app.removed = true;
4653                }
4654                service.app = null;
4655                services.add(service);
4656            }
4657        }
4658
4659        N = services.size();
4660        for (i=0; i<N; i++) {
4661            bringDownServiceLocked(services.get(i), true);
4662        }
4663
4664        resumeTopActivityLocked(null);
4665    }
4666
4667    private final boolean removeProcessLocked(ProcessRecord app, boolean callerWillRestart) {
4668        final String name = app.processName;
4669        final int uid = app.info.uid;
4670        if (Config.LOGD) Log.d(
4671            TAG, "Force removing process " + app + " (" + name
4672            + "/" + uid + ")");
4673
4674        mProcessNames.remove(name, uid);
4675        boolean needRestart = false;
4676        if (app.pid > 0 && app.pid != MY_PID) {
4677            int pid = app.pid;
4678            synchronized (mPidsSelfLocked) {
4679                mPidsSelfLocked.remove(pid);
4680                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4681            }
4682            handleAppDiedLocked(app, true);
4683            mLRUProcesses.remove(app);
4684            Process.killProcess(pid);
4685
4686            if (app.persistent) {
4687                if (!callerWillRestart) {
4688                    addAppLocked(app.info);
4689                } else {
4690                    needRestart = true;
4691                }
4692            }
4693        } else {
4694            mRemovedProcesses.add(app);
4695        }
4696
4697        return needRestart;
4698    }
4699
4700    private final void processStartTimedOutLocked(ProcessRecord app) {
4701        final int pid = app.pid;
4702        boolean gone = false;
4703        synchronized (mPidsSelfLocked) {
4704            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
4705            if (knownApp != null && knownApp.thread == null) {
4706                mPidsSelfLocked.remove(pid);
4707                gone = true;
4708            }
4709        }
4710
4711        if (gone) {
4712            Log.w(TAG, "Process " + app + " failed to attach");
4713            mProcessNames.remove(app.processName, app.info.uid);
4714            Process.killProcess(pid);
4715            if (mPendingBroadcast != null && mPendingBroadcast.curApp.pid == pid) {
4716                Log.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
4717                mPendingBroadcast = null;
4718                scheduleBroadcastsLocked();
4719            }
4720            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
4721                Log.w(TAG, "Unattached app died before backup, skipping");
4722                try {
4723                    IBackupManager bm = IBackupManager.Stub.asInterface(
4724                            ServiceManager.getService(Context.BACKUP_SERVICE));
4725                    bm.agentDisconnected(app.info.packageName);
4726                } catch (RemoteException e) {
4727                    // Can't happen; the backup manager is local
4728                }
4729            }
4730        } else {
4731            Log.w(TAG, "Spurious process start timeout - pid not known for " + app);
4732        }
4733    }
4734
4735    private final boolean attachApplicationLocked(IApplicationThread thread,
4736            int pid) {
4737
4738        // Find the application record that is being attached...  either via
4739        // the pid if we are running in multiple processes, or just pull the
4740        // next app record if we are emulating process with anonymous threads.
4741        ProcessRecord app;
4742        if (pid != MY_PID && pid >= 0) {
4743            synchronized (mPidsSelfLocked) {
4744                app = mPidsSelfLocked.get(pid);
4745            }
4746        } else if (mStartingProcesses.size() > 0) {
4747            app = mStartingProcesses.remove(0);
4748            app.setPid(pid);
4749        } else {
4750            app = null;
4751        }
4752
4753        if (app == null) {
4754            Log.w(TAG, "No pending application record for pid " + pid
4755                    + " (IApplicationThread " + thread + "); dropping process");
4756            EventLog.writeEvent(LOG_AM_DROP_PROCESS, pid);
4757            if (pid > 0 && pid != MY_PID) {
4758                Process.killProcess(pid);
4759            } else {
4760                try {
4761                    thread.scheduleExit();
4762                } catch (Exception e) {
4763                    // Ignore exceptions.
4764                }
4765            }
4766            return false;
4767        }
4768
4769        // If this application record is still attached to a previous
4770        // process, clean it up now.
4771        if (app.thread != null) {
4772            handleAppDiedLocked(app, true);
4773        }
4774
4775        // Tell the process all about itself.
4776
4777        if (localLOGV) Log.v(
4778                TAG, "Binding process pid " + pid + " to record " + app);
4779
4780        String processName = app.processName;
4781        try {
4782            thread.asBinder().linkToDeath(new AppDeathRecipient(
4783                    app, pid, thread), 0);
4784        } catch (RemoteException e) {
4785            app.resetPackageList();
4786            startProcessLocked(app, "link fail", processName);
4787            return false;
4788        }
4789
4790        EventLog.writeEvent(LOG_AM_PROCESS_BOUND, app.pid, app.processName);
4791
4792        app.thread = thread;
4793        app.curAdj = app.setAdj = -100;
4794        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
4795        app.forcingToForeground = null;
4796        app.foregroundServices = false;
4797        app.debugging = false;
4798
4799        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4800
4801        List providers = generateApplicationProvidersLocked(app);
4802
4803        if (localLOGV) Log.v(
4804            TAG, "New app record " + app
4805            + " thread=" + thread.asBinder() + " pid=" + pid);
4806        try {
4807            int testMode = IApplicationThread.DEBUG_OFF;
4808            if (mDebugApp != null && mDebugApp.equals(processName)) {
4809                testMode = mWaitForDebugger
4810                    ? IApplicationThread.DEBUG_WAIT
4811                    : IApplicationThread.DEBUG_ON;
4812                app.debugging = true;
4813                if (mDebugTransient) {
4814                    mDebugApp = mOrigDebugApp;
4815                    mWaitForDebugger = mOrigWaitForDebugger;
4816                }
4817            }
4818            // If the app is being launched for restore or full backup, set it up specially
4819            boolean isRestrictedBackupMode = false;
4820            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
4821                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
4822                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
4823            }
4824            thread.bindApplication(processName, app.instrumentationInfo != null
4825                    ? app.instrumentationInfo : app.info, providers,
4826                    app.instrumentationClass, app.instrumentationProfileFile,
4827                    app.instrumentationArguments, app.instrumentationWatcher, testMode,
4828                    isRestrictedBackupMode, mConfiguration, getCommonServicesLocked());
4829            updateLRUListLocked(app, false);
4830            app.lastRequestedGc = SystemClock.uptimeMillis();
4831        } catch (Exception e) {
4832            // todo: Yikes!  What should we do?  For now we will try to
4833            // start another process, but that could easily get us in
4834            // an infinite loop of restarting processes...
4835            Log.w(TAG, "Exception thrown during bind!", e);
4836
4837            app.resetPackageList();
4838            startProcessLocked(app, "bind fail", processName);
4839            return false;
4840        }
4841
4842        // Remove this record from the list of starting applications.
4843        mPersistentStartingProcesses.remove(app);
4844        mProcessesOnHold.remove(app);
4845
4846        boolean badApp = false;
4847        boolean didSomething = false;
4848
4849        // See if the top visible activity is waiting to run in this process...
4850        HistoryRecord hr = topRunningActivityLocked(null);
4851        if (hr != null) {
4852            if (hr.app == null && app.info.uid == hr.info.applicationInfo.uid
4853                    && processName.equals(hr.processName)) {
4854                try {
4855                    if (realStartActivityLocked(hr, app, true, true)) {
4856                        didSomething = true;
4857                    }
4858                } catch (Exception e) {
4859                    Log.w(TAG, "Exception in new application when starting activity "
4860                          + hr.intent.getComponent().flattenToShortString(), e);
4861                    badApp = true;
4862                }
4863            } else {
4864                ensureActivitiesVisibleLocked(hr, null, processName, 0);
4865            }
4866        }
4867
4868        // Find any services that should be running in this process...
4869        if (!badApp && mPendingServices.size() > 0) {
4870            ServiceRecord sr = null;
4871            try {
4872                for (int i=0; i<mPendingServices.size(); i++) {
4873                    sr = mPendingServices.get(i);
4874                    if (app.info.uid != sr.appInfo.uid
4875                            || !processName.equals(sr.processName)) {
4876                        continue;
4877                    }
4878
4879                    mPendingServices.remove(i);
4880                    i--;
4881                    realStartServiceLocked(sr, app);
4882                    didSomething = true;
4883                }
4884            } catch (Exception e) {
4885                Log.w(TAG, "Exception in new application when starting service "
4886                      + sr.shortName, e);
4887                badApp = true;
4888            }
4889        }
4890
4891        // Check if the next broadcast receiver is in this process...
4892        BroadcastRecord br = mPendingBroadcast;
4893        if (!badApp && br != null && br.curApp == app) {
4894            try {
4895                mPendingBroadcast = null;
4896                processCurBroadcastLocked(br, app);
4897                didSomething = true;
4898            } catch (Exception e) {
4899                Log.w(TAG, "Exception in new application when starting receiver "
4900                      + br.curComponent.flattenToShortString(), e);
4901                badApp = true;
4902                logBroadcastReceiverDiscard(br);
4903                finishReceiverLocked(br.receiver, br.resultCode, br.resultData,
4904                        br.resultExtras, br.resultAbort, true);
4905                scheduleBroadcastsLocked();
4906            }
4907        }
4908
4909        // Check whether the next backup agent is in this process...
4910        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.info.uid) {
4911            if (DEBUG_BACKUP) Log.v(TAG, "New app is backup target, launching agent for " + app);
4912            try {
4913                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, mBackupTarget.backupMode);
4914            } catch (Exception e) {
4915                Log.w(TAG, "Exception scheduling backup agent creation: ");
4916                e.printStackTrace();
4917            }
4918        }
4919
4920        if (badApp) {
4921            // todo: Also need to kill application to deal with all
4922            // kinds of exceptions.
4923            handleAppDiedLocked(app, false);
4924            return false;
4925        }
4926
4927        if (!didSomething) {
4928            updateOomAdjLocked();
4929        }
4930
4931        return true;
4932    }
4933
4934    public final void attachApplication(IApplicationThread thread) {
4935        synchronized (this) {
4936            int callingPid = Binder.getCallingPid();
4937            final long origId = Binder.clearCallingIdentity();
4938            attachApplicationLocked(thread, callingPid);
4939            Binder.restoreCallingIdentity(origId);
4940        }
4941    }
4942
4943    public final void activityIdle(IBinder token) {
4944        final long origId = Binder.clearCallingIdentity();
4945        activityIdleInternal(token, false);
4946        Binder.restoreCallingIdentity(origId);
4947    }
4948
4949    final ArrayList<HistoryRecord> processStoppingActivitiesLocked(
4950            boolean remove) {
4951        int N = mStoppingActivities.size();
4952        if (N <= 0) return null;
4953
4954        ArrayList<HistoryRecord> stops = null;
4955
4956        final boolean nowVisible = mResumedActivity != null
4957                && mResumedActivity.nowVisible
4958                && !mResumedActivity.waitingVisible;
4959        for (int i=0; i<N; i++) {
4960            HistoryRecord s = mStoppingActivities.get(i);
4961            if (localLOGV) Log.v(TAG, "Stopping " + s + ": nowVisible="
4962                    + nowVisible + " waitingVisible=" + s.waitingVisible
4963                    + " finishing=" + s.finishing);
4964            if (s.waitingVisible && nowVisible) {
4965                mWaitingVisibleActivities.remove(s);
4966                s.waitingVisible = false;
4967                if (s.finishing) {
4968                    // If this activity is finishing, it is sitting on top of
4969                    // everyone else but we now know it is no longer needed...
4970                    // so get rid of it.  Otherwise, we need to go through the
4971                    // normal flow and hide it once we determine that it is
4972                    // hidden by the activities in front of it.
4973                    if (localLOGV) Log.v(TAG, "Before stopping, can hide: " + s);
4974                    mWindowManager.setAppVisibility(s, false);
4975                }
4976            }
4977            if (!s.waitingVisible && remove) {
4978                if (localLOGV) Log.v(TAG, "Ready to stop: " + s);
4979                if (stops == null) {
4980                    stops = new ArrayList<HistoryRecord>();
4981                }
4982                stops.add(s);
4983                mStoppingActivities.remove(i);
4984                N--;
4985                i--;
4986            }
4987        }
4988
4989        return stops;
4990    }
4991
4992    void enableScreenAfterBoot() {
4993        mWindowManager.enableScreenAfterBoot();
4994    }
4995
4996    final void activityIdleInternal(IBinder token, boolean fromTimeout) {
4997        if (localLOGV) Log.v(TAG, "Activity idle: " + token);
4998
4999        ArrayList<HistoryRecord> stops = null;
5000        ArrayList<HistoryRecord> finishes = null;
5001        ArrayList<HistoryRecord> thumbnails = null;
5002        int NS = 0;
5003        int NF = 0;
5004        int NT = 0;
5005        IApplicationThread sendThumbnail = null;
5006        boolean booting = false;
5007        boolean enableScreen = false;
5008
5009        synchronized (this) {
5010            if (token != null) {
5011                mHandler.removeMessages(IDLE_TIMEOUT_MSG, token);
5012            }
5013
5014            // Get the activity record.
5015            int index = indexOfTokenLocked(token, false);
5016            if (index >= 0) {
5017                HistoryRecord r = (HistoryRecord)mHistory.get(index);
5018
5019                // No longer need to keep the device awake.
5020                if (mResumedActivity == r && mLaunchingActivity.isHeld()) {
5021                    mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
5022                    mLaunchingActivity.release();
5023                }
5024
5025                // We are now idle.  If someone is waiting for a thumbnail from
5026                // us, we can now deliver.
5027                r.idle = true;
5028                scheduleAppGcsLocked();
5029                if (r.thumbnailNeeded && r.app != null && r.app.thread != null) {
5030                    sendThumbnail = r.app.thread;
5031                    r.thumbnailNeeded = false;
5032                }
5033
5034                // If this activity is fullscreen, set up to hide those under it.
5035
5036                if (DEBUG_VISBILITY) Log.v(TAG, "Idle activity for " + r);
5037                ensureActivitiesVisibleLocked(null, 0);
5038
5039                //Log.i(TAG, "IDLE: mBooted=" + mBooted + ", fromTimeout=" + fromTimeout);
5040                if (!mBooted && !fromTimeout) {
5041                    mBooted = true;
5042                    enableScreen = true;
5043                }
5044            }
5045
5046            // Atomically retrieve all of the other things to do.
5047            stops = processStoppingActivitiesLocked(true);
5048            NS = stops != null ? stops.size() : 0;
5049            if ((NF=mFinishingActivities.size()) > 0) {
5050                finishes = new ArrayList<HistoryRecord>(mFinishingActivities);
5051                mFinishingActivities.clear();
5052            }
5053            if ((NT=mCancelledThumbnails.size()) > 0) {
5054                thumbnails = new ArrayList<HistoryRecord>(mCancelledThumbnails);
5055                mCancelledThumbnails.clear();
5056            }
5057
5058            booting = mBooting;
5059            mBooting = false;
5060        }
5061
5062        int i;
5063
5064        // Send thumbnail if requested.
5065        if (sendThumbnail != null) {
5066            try {
5067                sendThumbnail.requestThumbnail(token);
5068            } catch (Exception e) {
5069                Log.w(TAG, "Exception thrown when requesting thumbnail", e);
5070                sendPendingThumbnail(null, token, null, null, true);
5071            }
5072        }
5073
5074        // Stop any activities that are scheduled to do so but have been
5075        // waiting for the next one to start.
5076        for (i=0; i<NS; i++) {
5077            HistoryRecord r = (HistoryRecord)stops.get(i);
5078            synchronized (this) {
5079                if (r.finishing) {
5080                    finishCurrentActivityLocked(r, FINISH_IMMEDIATELY);
5081                } else {
5082                    stopActivityLocked(r);
5083                }
5084            }
5085        }
5086
5087        // Finish any activities that are scheduled to do so but have been
5088        // waiting for the next one to start.
5089        for (i=0; i<NF; i++) {
5090            HistoryRecord r = (HistoryRecord)finishes.get(i);
5091            synchronized (this) {
5092                destroyActivityLocked(r, true);
5093            }
5094        }
5095
5096        // Report back to any thumbnail receivers.
5097        for (i=0; i<NT; i++) {
5098            HistoryRecord r = (HistoryRecord)thumbnails.get(i);
5099            sendPendingThumbnail(r, null, null, null, true);
5100        }
5101
5102        if (booting) {
5103            // Ensure that any processes we had put on hold are now started
5104            // up.
5105            final int NP = mProcessesOnHold.size();
5106            if (NP > 0) {
5107                ArrayList<ProcessRecord> procs =
5108                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5109                for (int ip=0; ip<NP; ip++) {
5110                    this.startProcessLocked(procs.get(ip), "on-hold", null);
5111                }
5112            }
5113            if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
5114                // Tell anyone interested that we are done booting!
5115                synchronized (this) {
5116                    broadcastIntentLocked(null, null,
5117                            new Intent(Intent.ACTION_BOOT_COMPLETED, null),
5118                            null, null, 0, null, null,
5119                            android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5120                            false, false, MY_PID, Process.SYSTEM_UID);
5121                }
5122            }
5123        }
5124
5125        trimApplications();
5126        //dump();
5127        //mWindowManager.dump();
5128
5129        if (enableScreen) {
5130            EventLog.writeEvent(LOG_BOOT_PROGRESS_ENABLE_SCREEN,
5131                SystemClock.uptimeMillis());
5132            enableScreenAfterBoot();
5133        }
5134    }
5135
5136    final void ensureScreenEnabled() {
5137        boolean enableScreen;
5138        synchronized (this) {
5139            enableScreen = !mBooted;
5140            mBooted = true;
5141        }
5142
5143        if (enableScreen) {
5144            EventLog.writeEvent(LOG_BOOT_PROGRESS_ENABLE_SCREEN,
5145                SystemClock.uptimeMillis());
5146            enableScreenAfterBoot();
5147        }
5148    }
5149
5150    public final void activityPaused(IBinder token, Bundle icicle) {
5151        // Refuse possible leaked file descriptors
5152        if (icicle != null && icicle.hasFileDescriptors()) {
5153            throw new IllegalArgumentException("File descriptors passed in Bundle");
5154        }
5155
5156        final long origId = Binder.clearCallingIdentity();
5157        activityPaused(token, icicle, false);
5158        Binder.restoreCallingIdentity(origId);
5159    }
5160
5161    final void activityPaused(IBinder token, Bundle icicle, boolean timeout) {
5162        if (DEBUG_PAUSE) Log.v(
5163            TAG, "Activity paused: token=" + token + ", icicle=" + icicle
5164            + ", timeout=" + timeout);
5165
5166        HistoryRecord r = null;
5167
5168        synchronized (this) {
5169            int index = indexOfTokenLocked(token, false);
5170            if (index >= 0) {
5171                r = (HistoryRecord)mHistory.get(index);
5172                if (!timeout) {
5173                    r.icicle = icicle;
5174                    r.haveState = true;
5175                }
5176                mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);
5177                if (mPausingActivity == r) {
5178                    r.state = ActivityState.PAUSED;
5179                    completePauseLocked();
5180                } else {
5181                	EventLog.writeEvent(LOG_AM_FAILED_TO_PAUSE_ACTIVITY,
5182                	        System.identityHashCode(r), r.shortComponentName,
5183                			mPausingActivity != null
5184                			    ? mPausingActivity.shortComponentName : "(none)");
5185                }
5186            }
5187        }
5188    }
5189
5190    public final void activityStopped(IBinder token, Bitmap thumbnail,
5191            CharSequence description) {
5192        if (localLOGV) Log.v(
5193            TAG, "Activity stopped: token=" + token);
5194
5195        HistoryRecord r = null;
5196
5197        final long origId = Binder.clearCallingIdentity();
5198
5199        synchronized (this) {
5200            int index = indexOfTokenLocked(token, false);
5201            if (index >= 0) {
5202                r = (HistoryRecord)mHistory.get(index);
5203                r.thumbnail = thumbnail;
5204                r.description = description;
5205                r.stopped = true;
5206                r.state = ActivityState.STOPPED;
5207                if (!r.finishing) {
5208                    if (r.configDestroy) {
5209                        destroyActivityLocked(r, true);
5210                        resumeTopActivityLocked(null);
5211                    }
5212                }
5213            }
5214        }
5215
5216        if (r != null) {
5217            sendPendingThumbnail(r, null, null, null, false);
5218        }
5219
5220        trimApplications();
5221
5222        Binder.restoreCallingIdentity(origId);
5223    }
5224
5225    public final void activityDestroyed(IBinder token) {
5226        if (DEBUG_SWITCH) Log.v(TAG, "ACTIVITY DESTROYED: " + token);
5227        synchronized (this) {
5228            mHandler.removeMessages(DESTROY_TIMEOUT_MSG, token);
5229
5230            int index = indexOfTokenLocked(token, false);
5231            if (index >= 0) {
5232                HistoryRecord r = (HistoryRecord)mHistory.get(index);
5233                if (r.state == ActivityState.DESTROYING) {
5234                    final long origId = Binder.clearCallingIdentity();
5235                    removeActivityFromHistoryLocked(r);
5236                    Binder.restoreCallingIdentity(origId);
5237                }
5238            }
5239        }
5240    }
5241
5242    public String getCallingPackage(IBinder token) {
5243        synchronized (this) {
5244            HistoryRecord r = getCallingRecordLocked(token);
5245            return r != null && r.app != null ? r.app.processName : null;
5246        }
5247    }
5248
5249    public ComponentName getCallingActivity(IBinder token) {
5250        synchronized (this) {
5251            HistoryRecord r = getCallingRecordLocked(token);
5252            return r != null ? r.intent.getComponent() : null;
5253        }
5254    }
5255
5256    private HistoryRecord getCallingRecordLocked(IBinder token) {
5257        int index = indexOfTokenLocked(token, true);
5258        if (index >= 0) {
5259            HistoryRecord r = (HistoryRecord)mHistory.get(index);
5260            if (r != null) {
5261                return r.resultTo;
5262            }
5263        }
5264        return null;
5265    }
5266
5267    public ComponentName getActivityClassForToken(IBinder token) {
5268        synchronized(this) {
5269            int index = indexOfTokenLocked(token, false);
5270            if (index >= 0) {
5271                HistoryRecord r = (HistoryRecord)mHistory.get(index);
5272                return r.intent.getComponent();
5273            }
5274            return null;
5275        }
5276    }
5277
5278    public String getPackageForToken(IBinder token) {
5279        synchronized(this) {
5280            int index = indexOfTokenLocked(token, false);
5281            if (index >= 0) {
5282                HistoryRecord r = (HistoryRecord)mHistory.get(index);
5283                return r.packageName;
5284            }
5285            return null;
5286        }
5287    }
5288
5289    public IIntentSender getIntentSender(int type,
5290            String packageName, IBinder token, String resultWho,
5291            int requestCode, Intent intent, String resolvedType, int flags) {
5292        // Refuse possible leaked file descriptors
5293        if (intent != null && intent.hasFileDescriptors() == true) {
5294            throw new IllegalArgumentException("File descriptors passed in Intent");
5295        }
5296
5297        synchronized(this) {
5298            int callingUid = Binder.getCallingUid();
5299            try {
5300                if (callingUid != 0 && callingUid != Process.SYSTEM_UID &&
5301                        Process.supportsProcesses()) {
5302                    int uid = ActivityThread.getPackageManager()
5303                            .getPackageUid(packageName);
5304                    if (uid != Binder.getCallingUid()) {
5305                        String msg = "Permission Denial: getIntentSender() from pid="
5306                            + Binder.getCallingPid()
5307                            + ", uid=" + Binder.getCallingUid()
5308                            + ", (need uid=" + uid + ")"
5309                            + " is not allowed to send as package " + packageName;
5310                        Log.w(TAG, msg);
5311                        throw new SecurityException(msg);
5312                    }
5313                }
5314            } catch (RemoteException e) {
5315                throw new SecurityException(e);
5316            }
5317            HistoryRecord activity = null;
5318            if (type == INTENT_SENDER_ACTIVITY_RESULT) {
5319                int index = indexOfTokenLocked(token, false);
5320                if (index < 0) {
5321                    return null;
5322                }
5323                activity = (HistoryRecord)mHistory.get(index);
5324                if (activity.finishing) {
5325                    return null;
5326                }
5327            }
5328
5329            final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5330            final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5331            final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5332            flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5333                    |PendingIntent.FLAG_UPDATE_CURRENT);
5334
5335            PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5336                    type, packageName, activity, resultWho,
5337                    requestCode, intent, resolvedType, flags);
5338            WeakReference<PendingIntentRecord> ref;
5339            ref = mIntentSenderRecords.get(key);
5340            PendingIntentRecord rec = ref != null ? ref.get() : null;
5341            if (rec != null) {
5342                if (!cancelCurrent) {
5343                    if (updateCurrent) {
5344                        rec.key.requestIntent.replaceExtras(intent);
5345                    }
5346                    return rec;
5347                }
5348                rec.canceled = true;
5349                mIntentSenderRecords.remove(key);
5350            }
5351            if (noCreate) {
5352                return rec;
5353            }
5354            rec = new PendingIntentRecord(this, key, callingUid);
5355            mIntentSenderRecords.put(key, rec.ref);
5356            if (type == INTENT_SENDER_ACTIVITY_RESULT) {
5357                if (activity.pendingResults == null) {
5358                    activity.pendingResults
5359                            = new HashSet<WeakReference<PendingIntentRecord>>();
5360                }
5361                activity.pendingResults.add(rec.ref);
5362            }
5363            return rec;
5364        }
5365    }
5366
5367    public void cancelIntentSender(IIntentSender sender) {
5368        if (!(sender instanceof PendingIntentRecord)) {
5369            return;
5370        }
5371        synchronized(this) {
5372            PendingIntentRecord rec = (PendingIntentRecord)sender;
5373            try {
5374                int uid = ActivityThread.getPackageManager()
5375                        .getPackageUid(rec.key.packageName);
5376                if (uid != Binder.getCallingUid()) {
5377                    String msg = "Permission Denial: cancelIntentSender() from pid="
5378                        + Binder.getCallingPid()
5379                        + ", uid=" + Binder.getCallingUid()
5380                        + " is not allowed to cancel packges "
5381                        + rec.key.packageName;
5382                    Log.w(TAG, msg);
5383                    throw new SecurityException(msg);
5384                }
5385            } catch (RemoteException e) {
5386                throw new SecurityException(e);
5387            }
5388            cancelIntentSenderLocked(rec, true);
5389        }
5390    }
5391
5392    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5393        rec.canceled = true;
5394        mIntentSenderRecords.remove(rec.key);
5395        if (cleanActivity && rec.key.activity != null) {
5396            rec.key.activity.pendingResults.remove(rec.ref);
5397        }
5398    }
5399
5400    public String getPackageForIntentSender(IIntentSender pendingResult) {
5401        if (!(pendingResult instanceof PendingIntentRecord)) {
5402            return null;
5403        }
5404        synchronized(this) {
5405            try {
5406                PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5407                return res.key.packageName;
5408            } catch (ClassCastException e) {
5409            }
5410        }
5411        return null;
5412    }
5413
5414    public void setProcessLimit(int max) {
5415        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5416                "setProcessLimit()");
5417        mProcessLimit = max;
5418    }
5419
5420    public int getProcessLimit() {
5421        return mProcessLimit;
5422    }
5423
5424    void foregroundTokenDied(ForegroundToken token) {
5425        synchronized (ActivityManagerService.this) {
5426            synchronized (mPidsSelfLocked) {
5427                ForegroundToken cur
5428                    = mForegroundProcesses.get(token.pid);
5429                if (cur != token) {
5430                    return;
5431                }
5432                mForegroundProcesses.remove(token.pid);
5433                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
5434                if (pr == null) {
5435                    return;
5436                }
5437                pr.forcingToForeground = null;
5438                pr.foregroundServices = false;
5439            }
5440            updateOomAdjLocked();
5441        }
5442    }
5443
5444    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
5445        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5446                "setProcessForeground()");
5447        synchronized(this) {
5448            boolean changed = false;
5449
5450            synchronized (mPidsSelfLocked) {
5451                ProcessRecord pr = mPidsSelfLocked.get(pid);
5452                if (pr == null) {
5453                    Log.w(TAG, "setProcessForeground called on unknown pid: " + pid);
5454                    return;
5455                }
5456                ForegroundToken oldToken = mForegroundProcesses.get(pid);
5457                if (oldToken != null) {
5458                    oldToken.token.unlinkToDeath(oldToken, 0);
5459                    mForegroundProcesses.remove(pid);
5460                    pr.forcingToForeground = null;
5461                    changed = true;
5462                }
5463                if (isForeground && token != null) {
5464                    ForegroundToken newToken = new ForegroundToken() {
5465                        public void binderDied() {
5466                            foregroundTokenDied(this);
5467                        }
5468                    };
5469                    newToken.pid = pid;
5470                    newToken.token = token;
5471                    try {
5472                        token.linkToDeath(newToken, 0);
5473                        mForegroundProcesses.put(pid, newToken);
5474                        pr.forcingToForeground = token;
5475                        changed = true;
5476                    } catch (RemoteException e) {
5477                        // If the process died while doing this, we will later
5478                        // do the cleanup with the process death link.
5479                    }
5480                }
5481            }
5482
5483            if (changed) {
5484                updateOomAdjLocked();
5485            }
5486        }
5487    }
5488
5489    // =========================================================
5490    // PERMISSIONS
5491    // =========================================================
5492
5493    static class PermissionController extends IPermissionController.Stub {
5494        ActivityManagerService mActivityManagerService;
5495        PermissionController(ActivityManagerService activityManagerService) {
5496            mActivityManagerService = activityManagerService;
5497        }
5498
5499        public boolean checkPermission(String permission, int pid, int uid) {
5500            return mActivityManagerService.checkPermission(permission, pid,
5501                    uid) == PackageManager.PERMISSION_GRANTED;
5502        }
5503    }
5504
5505    /**
5506     * This can be called with or without the global lock held.
5507     */
5508    int checkComponentPermission(String permission, int pid, int uid,
5509            int reqUid) {
5510        // We might be performing an operation on behalf of an indirect binder
5511        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
5512        // client identity accordingly before proceeding.
5513        Identity tlsIdentity = sCallerIdentity.get();
5514        if (tlsIdentity != null) {
5515            Log.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
5516                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
5517            uid = tlsIdentity.uid;
5518            pid = tlsIdentity.pid;
5519        }
5520
5521        // Root, system server and our own process get to do everything.
5522        if (uid == 0 || uid == Process.SYSTEM_UID || pid == MY_PID ||
5523            !Process.supportsProcesses()) {
5524            return PackageManager.PERMISSION_GRANTED;
5525        }
5526        // If the target requires a specific UID, always fail for others.
5527        if (reqUid >= 0 && uid != reqUid) {
5528            return PackageManager.PERMISSION_DENIED;
5529        }
5530        if (permission == null) {
5531            return PackageManager.PERMISSION_GRANTED;
5532        }
5533        try {
5534            return ActivityThread.getPackageManager()
5535                    .checkUidPermission(permission, uid);
5536        } catch (RemoteException e) {
5537            // Should never happen, but if it does... deny!
5538            Log.e(TAG, "PackageManager is dead?!?", e);
5539        }
5540        return PackageManager.PERMISSION_DENIED;
5541    }
5542
5543    /**
5544     * As the only public entry point for permissions checking, this method
5545     * can enforce the semantic that requesting a check on a null global
5546     * permission is automatically denied.  (Internally a null permission
5547     * string is used when calling {@link #checkComponentPermission} in cases
5548     * when only uid-based security is needed.)
5549     *
5550     * This can be called with or without the global lock held.
5551     */
5552    public int checkPermission(String permission, int pid, int uid) {
5553        if (permission == null) {
5554            return PackageManager.PERMISSION_DENIED;
5555        }
5556        return checkComponentPermission(permission, pid, uid, -1);
5557    }
5558
5559    /**
5560     * Binder IPC calls go through the public entry point.
5561     * This can be called with or without the global lock held.
5562     */
5563    int checkCallingPermission(String permission) {
5564        return checkPermission(permission,
5565                Binder.getCallingPid(),
5566                Binder.getCallingUid());
5567    }
5568
5569    /**
5570     * This can be called with or without the global lock held.
5571     */
5572    void enforceCallingPermission(String permission, String func) {
5573        if (checkCallingPermission(permission)
5574                == PackageManager.PERMISSION_GRANTED) {
5575            return;
5576        }
5577
5578        String msg = "Permission Denial: " + func + " from pid="
5579                + Binder.getCallingPid()
5580                + ", uid=" + Binder.getCallingUid()
5581                + " requires " + permission;
5582        Log.w(TAG, msg);
5583        throw new SecurityException(msg);
5584    }
5585
5586    private final boolean checkHoldingPermissionsLocked(IPackageManager pm,
5587            ProviderInfo pi, int uid, int modeFlags) {
5588        try {
5589            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
5590                if ((pi.readPermission != null) &&
5591                        (pm.checkUidPermission(pi.readPermission, uid)
5592                                != PackageManager.PERMISSION_GRANTED)) {
5593                    return false;
5594                }
5595            }
5596            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
5597                if ((pi.writePermission != null) &&
5598                        (pm.checkUidPermission(pi.writePermission, uid)
5599                                != PackageManager.PERMISSION_GRANTED)) {
5600                    return false;
5601                }
5602            }
5603            return true;
5604        } catch (RemoteException e) {
5605            return false;
5606        }
5607    }
5608
5609    private final boolean checkUriPermissionLocked(Uri uri, int uid,
5610            int modeFlags) {
5611        // Root gets to do everything.
5612        if (uid == 0 || !Process.supportsProcesses()) {
5613            return true;
5614        }
5615        HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
5616        if (perms == null) return false;
5617        UriPermission perm = perms.get(uri);
5618        if (perm == null) return false;
5619        return (modeFlags&perm.modeFlags) == modeFlags;
5620    }
5621
5622    public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
5623        // Another redirected-binder-call permissions check as in
5624        // {@link checkComponentPermission}.
5625        Identity tlsIdentity = sCallerIdentity.get();
5626        if (tlsIdentity != null) {
5627            uid = tlsIdentity.uid;
5628            pid = tlsIdentity.pid;
5629        }
5630
5631        // Our own process gets to do everything.
5632        if (pid == MY_PID) {
5633            return PackageManager.PERMISSION_GRANTED;
5634        }
5635        synchronized(this) {
5636            return checkUriPermissionLocked(uri, uid, modeFlags)
5637                    ? PackageManager.PERMISSION_GRANTED
5638                    : PackageManager.PERMISSION_DENIED;
5639        }
5640    }
5641
5642    private void grantUriPermissionLocked(int callingUid,
5643            String targetPkg, Uri uri, int modeFlags, HistoryRecord activity) {
5644        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5645                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5646        if (modeFlags == 0) {
5647            return;
5648        }
5649
5650        final IPackageManager pm = ActivityThread.getPackageManager();
5651
5652        // If this is not a content: uri, we can't do anything with it.
5653        if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
5654            return;
5655        }
5656
5657        String name = uri.getAuthority();
5658        ProviderInfo pi = null;
5659        ContentProviderRecord cpr
5660                = (ContentProviderRecord)mProvidersByName.get(name);
5661        if (cpr != null) {
5662            pi = cpr.info;
5663        } else {
5664            try {
5665                pi = pm.resolveContentProvider(name,
5666                        PackageManager.GET_URI_PERMISSION_PATTERNS);
5667            } catch (RemoteException ex) {
5668            }
5669        }
5670        if (pi == null) {
5671            Log.w(TAG, "No content provider found for: " + name);
5672            return;
5673        }
5674
5675        int targetUid;
5676        try {
5677            targetUid = pm.getPackageUid(targetPkg);
5678            if (targetUid < 0) {
5679                return;
5680            }
5681        } catch (RemoteException ex) {
5682            return;
5683        }
5684
5685        // First...  does the target actually need this permission?
5686        if (checkHoldingPermissionsLocked(pm, pi, targetUid, modeFlags)) {
5687            // No need to grant the target this permission.
5688            return;
5689        }
5690
5691        // Second...  maybe someone else has already granted the
5692        // permission?
5693        if (checkUriPermissionLocked(uri, targetUid, modeFlags)) {
5694            // No need to grant the target this permission.
5695            return;
5696        }
5697
5698        // Third...  is the provider allowing granting of URI permissions?
5699        if (!pi.grantUriPermissions) {
5700            throw new SecurityException("Provider " + pi.packageName
5701                    + "/" + pi.name
5702                    + " does not allow granting of Uri permissions (uri "
5703                    + uri + ")");
5704        }
5705        if (pi.uriPermissionPatterns != null) {
5706            final int N = pi.uriPermissionPatterns.length;
5707            boolean allowed = false;
5708            for (int i=0; i<N; i++) {
5709                if (pi.uriPermissionPatterns[i] != null
5710                        && pi.uriPermissionPatterns[i].match(uri.getPath())) {
5711                    allowed = true;
5712                    break;
5713                }
5714            }
5715            if (!allowed) {
5716                throw new SecurityException("Provider " + pi.packageName
5717                        + "/" + pi.name
5718                        + " does not allow granting of permission to path of Uri "
5719                        + uri);
5720            }
5721        }
5722
5723        // Fourth...  does the caller itself have permission to access
5724        // this uri?
5725        if (!checkHoldingPermissionsLocked(pm, pi, callingUid, modeFlags)) {
5726            if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
5727                throw new SecurityException("Uid " + callingUid
5728                        + " does not have permission to uri " + uri);
5729            }
5730        }
5731
5732        // Okay!  So here we are: the caller has the assumed permission
5733        // to the uri, and the target doesn't.  Let's now give this to
5734        // the target.
5735
5736        HashMap<Uri, UriPermission> targetUris
5737                = mGrantedUriPermissions.get(targetUid);
5738        if (targetUris == null) {
5739            targetUris = new HashMap<Uri, UriPermission>();
5740            mGrantedUriPermissions.put(targetUid, targetUris);
5741        }
5742
5743        UriPermission perm = targetUris.get(uri);
5744        if (perm == null) {
5745            perm = new UriPermission(targetUid, uri);
5746            targetUris.put(uri, perm);
5747
5748        }
5749        perm.modeFlags |= modeFlags;
5750        if (activity == null) {
5751            perm.globalModeFlags |= modeFlags;
5752        } else if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
5753            perm.readActivities.add(activity);
5754            if (activity.readUriPermissions == null) {
5755                activity.readUriPermissions = new HashSet<UriPermission>();
5756            }
5757            activity.readUriPermissions.add(perm);
5758        } else if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
5759            perm.writeActivities.add(activity);
5760            if (activity.writeUriPermissions == null) {
5761                activity.writeUriPermissions = new HashSet<UriPermission>();
5762            }
5763            activity.writeUriPermissions.add(perm);
5764        }
5765    }
5766
5767    private void grantUriPermissionFromIntentLocked(int callingUid,
5768            String targetPkg, Intent intent, HistoryRecord activity) {
5769        if (intent == null) {
5770            return;
5771        }
5772        Uri data = intent.getData();
5773        if (data == null) {
5774            return;
5775        }
5776        grantUriPermissionLocked(callingUid, targetPkg, data,
5777                intent.getFlags(), activity);
5778    }
5779
5780    public void grantUriPermission(IApplicationThread caller, String targetPkg,
5781            Uri uri, int modeFlags) {
5782        synchronized(this) {
5783            final ProcessRecord r = getRecordForAppLocked(caller);
5784            if (r == null) {
5785                throw new SecurityException("Unable to find app for caller "
5786                        + caller
5787                        + " when granting permission to uri " + uri);
5788            }
5789            if (targetPkg == null) {
5790                Log.w(TAG, "grantUriPermission: null target");
5791                return;
5792            }
5793            if (uri == null) {
5794                Log.w(TAG, "grantUriPermission: null uri");
5795                return;
5796            }
5797
5798            grantUriPermissionLocked(r.info.uid, targetPkg, uri, modeFlags,
5799                    null);
5800        }
5801    }
5802
5803    private void removeUriPermissionIfNeededLocked(UriPermission perm) {
5804        if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
5805                |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
5806            HashMap<Uri, UriPermission> perms
5807                    = mGrantedUriPermissions.get(perm.uid);
5808            if (perms != null) {
5809                perms.remove(perm.uri);
5810                if (perms.size() == 0) {
5811                    mGrantedUriPermissions.remove(perm.uid);
5812                }
5813            }
5814        }
5815    }
5816
5817    private void removeActivityUriPermissionsLocked(HistoryRecord activity) {
5818        if (activity.readUriPermissions != null) {
5819            for (UriPermission perm : activity.readUriPermissions) {
5820                perm.readActivities.remove(activity);
5821                if (perm.readActivities.size() == 0 && (perm.globalModeFlags
5822                        &Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0) {
5823                    perm.modeFlags &= ~Intent.FLAG_GRANT_READ_URI_PERMISSION;
5824                    removeUriPermissionIfNeededLocked(perm);
5825                }
5826            }
5827        }
5828        if (activity.writeUriPermissions != null) {
5829            for (UriPermission perm : activity.writeUriPermissions) {
5830                perm.writeActivities.remove(activity);
5831                if (perm.writeActivities.size() == 0 && (perm.globalModeFlags
5832                        &Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0) {
5833                    perm.modeFlags &= ~Intent.FLAG_GRANT_WRITE_URI_PERMISSION;
5834                    removeUriPermissionIfNeededLocked(perm);
5835                }
5836            }
5837        }
5838    }
5839
5840    private void revokeUriPermissionLocked(int callingUid, Uri uri,
5841            int modeFlags) {
5842        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5843                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5844        if (modeFlags == 0) {
5845            return;
5846        }
5847
5848        final IPackageManager pm = ActivityThread.getPackageManager();
5849
5850        final String authority = uri.getAuthority();
5851        ProviderInfo pi = null;
5852        ContentProviderRecord cpr
5853                = (ContentProviderRecord)mProvidersByName.get(authority);
5854        if (cpr != null) {
5855            pi = cpr.info;
5856        } else {
5857            try {
5858                pi = pm.resolveContentProvider(authority,
5859                        PackageManager.GET_URI_PERMISSION_PATTERNS);
5860            } catch (RemoteException ex) {
5861            }
5862        }
5863        if (pi == null) {
5864            Log.w(TAG, "No content provider found for: " + authority);
5865            return;
5866        }
5867
5868        // Does the caller have this permission on the URI?
5869        if (!checkHoldingPermissionsLocked(pm, pi, callingUid, modeFlags)) {
5870            // Right now, if you are not the original owner of the permission,
5871            // you are not allowed to revoke it.
5872            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
5873                throw new SecurityException("Uid " + callingUid
5874                        + " does not have permission to uri " + uri);
5875            //}
5876        }
5877
5878        // Go through all of the permissions and remove any that match.
5879        final List<String> SEGMENTS = uri.getPathSegments();
5880        if (SEGMENTS != null) {
5881            final int NS = SEGMENTS.size();
5882            int N = mGrantedUriPermissions.size();
5883            for (int i=0; i<N; i++) {
5884                HashMap<Uri, UriPermission> perms
5885                        = mGrantedUriPermissions.valueAt(i);
5886                Iterator<UriPermission> it = perms.values().iterator();
5887            toploop:
5888                while (it.hasNext()) {
5889                    UriPermission perm = it.next();
5890                    Uri targetUri = perm.uri;
5891                    if (!authority.equals(targetUri.getAuthority())) {
5892                        continue;
5893                    }
5894                    List<String> targetSegments = targetUri.getPathSegments();
5895                    if (targetSegments == null) {
5896                        continue;
5897                    }
5898                    if (targetSegments.size() < NS) {
5899                        continue;
5900                    }
5901                    for (int j=0; j<NS; j++) {
5902                        if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
5903                            continue toploop;
5904                        }
5905                    }
5906                    perm.clearModes(modeFlags);
5907                    if (perm.modeFlags == 0) {
5908                        it.remove();
5909                    }
5910                }
5911                if (perms.size() == 0) {
5912                    mGrantedUriPermissions.remove(
5913                            mGrantedUriPermissions.keyAt(i));
5914                    N--;
5915                    i--;
5916                }
5917            }
5918        }
5919    }
5920
5921    public void revokeUriPermission(IApplicationThread caller, Uri uri,
5922            int modeFlags) {
5923        synchronized(this) {
5924            final ProcessRecord r = getRecordForAppLocked(caller);
5925            if (r == null) {
5926                throw new SecurityException("Unable to find app for caller "
5927                        + caller
5928                        + " when revoking permission to uri " + uri);
5929            }
5930            if (uri == null) {
5931                Log.w(TAG, "revokeUriPermission: null uri");
5932                return;
5933            }
5934
5935            modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5936                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5937            if (modeFlags == 0) {
5938                return;
5939            }
5940
5941            final IPackageManager pm = ActivityThread.getPackageManager();
5942
5943            final String authority = uri.getAuthority();
5944            ProviderInfo pi = null;
5945            ContentProviderRecord cpr
5946                    = (ContentProviderRecord)mProvidersByName.get(authority);
5947            if (cpr != null) {
5948                pi = cpr.info;
5949            } else {
5950                try {
5951                    pi = pm.resolveContentProvider(authority,
5952                            PackageManager.GET_URI_PERMISSION_PATTERNS);
5953                } catch (RemoteException ex) {
5954                }
5955            }
5956            if (pi == null) {
5957                Log.w(TAG, "No content provider found for: " + authority);
5958                return;
5959            }
5960
5961            revokeUriPermissionLocked(r.info.uid, uri, modeFlags);
5962        }
5963    }
5964
5965    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
5966        synchronized (this) {
5967            ProcessRecord app =
5968                who != null ? getRecordForAppLocked(who) : null;
5969            if (app == null) return;
5970
5971            Message msg = Message.obtain();
5972            msg.what = WAIT_FOR_DEBUGGER_MSG;
5973            msg.obj = app;
5974            msg.arg1 = waiting ? 1 : 0;
5975            mHandler.sendMessage(msg);
5976        }
5977    }
5978
5979    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
5980        outInfo.availMem = Process.getFreeMemory();
5981        outInfo.threshold = HOME_APP_MEM;
5982        outInfo.lowMemory = outInfo.availMem <
5983                (HOME_APP_MEM + ((HIDDEN_APP_MEM-HOME_APP_MEM)/2));
5984    }
5985
5986    // =========================================================
5987    // TASK MANAGEMENT
5988    // =========================================================
5989
5990    public List getTasks(int maxNum, int flags,
5991                         IThumbnailReceiver receiver) {
5992        ArrayList list = new ArrayList();
5993
5994        PendingThumbnailsRecord pending = null;
5995        IApplicationThread topThumbnail = null;
5996        HistoryRecord topRecord = null;
5997
5998        synchronized(this) {
5999            if (localLOGV) Log.v(
6000                TAG, "getTasks: max=" + maxNum + ", flags=" + flags
6001                + ", receiver=" + receiver);
6002
6003            if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
6004                    != PackageManager.PERMISSION_GRANTED) {
6005                if (receiver != null) {
6006                    // If the caller wants to wait for pending thumbnails,
6007                    // it ain't gonna get them.
6008                    try {
6009                        receiver.finished();
6010                    } catch (RemoteException ex) {
6011                    }
6012                }
6013                String msg = "Permission Denial: getTasks() from pid="
6014                        + Binder.getCallingPid()
6015                        + ", uid=" + Binder.getCallingUid()
6016                        + " requires " + android.Manifest.permission.GET_TASKS;
6017                Log.w(TAG, msg);
6018                throw new SecurityException(msg);
6019            }
6020
6021            int pos = mHistory.size()-1;
6022            HistoryRecord next =
6023                pos >= 0 ? (HistoryRecord)mHistory.get(pos) : null;
6024            HistoryRecord top = null;
6025            CharSequence topDescription = null;
6026            TaskRecord curTask = null;
6027            int numActivities = 0;
6028            int numRunning = 0;
6029            while (pos >= 0 && maxNum > 0) {
6030                final HistoryRecord r = next;
6031                pos--;
6032                next = pos >= 0 ? (HistoryRecord)mHistory.get(pos) : null;
6033
6034                // Initialize state for next task if needed.
6035                if (top == null ||
6036                        (top.state == ActivityState.INITIALIZING
6037                            && top.task == r.task)) {
6038                    top = r;
6039                    topDescription = r.description;
6040                    curTask = r.task;
6041                    numActivities = numRunning = 0;
6042                }
6043
6044                // Add 'r' into the current task.
6045                numActivities++;
6046                if (r.app != null && r.app.thread != null) {
6047                    numRunning++;
6048                }
6049                if (topDescription == null) {
6050                    topDescription = r.description;
6051                }
6052
6053                if (localLOGV) Log.v(
6054                    TAG, r.intent.getComponent().flattenToShortString()
6055                    + ": task=" + r.task);
6056
6057                // If the next one is a different task, generate a new
6058                // TaskInfo entry for what we have.
6059                if (next == null || next.task != curTask) {
6060                    ActivityManager.RunningTaskInfo ci
6061                            = new ActivityManager.RunningTaskInfo();
6062                    ci.id = curTask.taskId;
6063                    ci.baseActivity = r.intent.getComponent();
6064                    ci.topActivity = top.intent.getComponent();
6065                    ci.thumbnail = top.thumbnail;
6066                    ci.description = topDescription;
6067                    ci.numActivities = numActivities;
6068                    ci.numRunning = numRunning;
6069                    //System.out.println(
6070                    //    "#" + maxNum + ": " + " descr=" + ci.description);
6071                    if (ci.thumbnail == null && receiver != null) {
6072                        if (localLOGV) Log.v(
6073                            TAG, "State=" + top.state + "Idle=" + top.idle
6074                            + " app=" + top.app
6075                            + " thr=" + (top.app != null ? top.app.thread : null));
6076                        if (top.state == ActivityState.RESUMED
6077                                || top.state == ActivityState.PAUSING) {
6078                            if (top.idle && top.app != null
6079                                && top.app.thread != null) {
6080                                topRecord = top;
6081                                topThumbnail = top.app.thread;
6082                            } else {
6083                                top.thumbnailNeeded = true;
6084                            }
6085                        }
6086                        if (pending == null) {
6087                            pending = new PendingThumbnailsRecord(receiver);
6088                        }
6089                        pending.pendingRecords.add(top);
6090                    }
6091                    list.add(ci);
6092                    maxNum--;
6093                    top = null;
6094                }
6095            }
6096
6097            if (pending != null) {
6098                mPendingThumbnails.add(pending);
6099            }
6100        }
6101
6102        if (localLOGV) Log.v(TAG, "We have pending thumbnails: " + pending);
6103
6104        if (topThumbnail != null) {
6105            if (localLOGV) Log.v(TAG, "Requesting top thumbnail");
6106            try {
6107                topThumbnail.requestThumbnail(topRecord);
6108            } catch (Exception e) {
6109                Log.w(TAG, "Exception thrown when requesting thumbnail", e);
6110                sendPendingThumbnail(null, topRecord, null, null, true);
6111            }
6112        }
6113
6114        if (pending == null && receiver != null) {
6115            // In this case all thumbnails were available and the client
6116            // is being asked to be told when the remaining ones come in...
6117            // which is unusually, since the top-most currently running
6118            // activity should never have a canned thumbnail!  Oh well.
6119            try {
6120                receiver.finished();
6121            } catch (RemoteException ex) {
6122            }
6123        }
6124
6125        return list;
6126    }
6127
6128    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
6129            int flags) {
6130        synchronized (this) {
6131            enforceCallingPermission(android.Manifest.permission.GET_TASKS,
6132                    "getRecentTasks()");
6133
6134            final int N = mRecentTasks.size();
6135            ArrayList<ActivityManager.RecentTaskInfo> res
6136                    = new ArrayList<ActivityManager.RecentTaskInfo>(
6137                            maxNum < N ? maxNum : N);
6138            for (int i=0; i<N && maxNum > 0; i++) {
6139                TaskRecord tr = mRecentTasks.get(i);
6140                if (((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
6141                        || (tr.intent == null)
6142                        || ((tr.intent.getFlags()
6143                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
6144                    ActivityManager.RecentTaskInfo rti
6145                            = new ActivityManager.RecentTaskInfo();
6146                    rti.id = tr.numActivities > 0 ? tr.taskId : -1;
6147                    rti.baseIntent = new Intent(
6148                            tr.intent != null ? tr.intent : tr.affinityIntent);
6149                    rti.origActivity = tr.origActivity;
6150                    res.add(rti);
6151                    maxNum--;
6152                }
6153            }
6154            return res;
6155        }
6156    }
6157
6158    private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
6159        int j;
6160        TaskRecord startTask = ((HistoryRecord)mHistory.get(startIndex)).task;
6161        TaskRecord jt = startTask;
6162
6163        // First look backwards
6164        for (j=startIndex-1; j>=0; j--) {
6165            HistoryRecord r = (HistoryRecord)mHistory.get(j);
6166            if (r.task != jt) {
6167                jt = r.task;
6168                if (affinity.equals(jt.affinity)) {
6169                    return j;
6170                }
6171            }
6172        }
6173
6174        // Now look forwards
6175        final int N = mHistory.size();
6176        jt = startTask;
6177        for (j=startIndex+1; j<N; j++) {
6178            HistoryRecord r = (HistoryRecord)mHistory.get(j);
6179            if (r.task != jt) {
6180                if (affinity.equals(jt.affinity)) {
6181                    return j;
6182                }
6183                jt = r.task;
6184            }
6185        }
6186
6187        // Might it be at the top?
6188        if (affinity.equals(((HistoryRecord)mHistory.get(N-1)).task.affinity)) {
6189            return N-1;
6190        }
6191
6192        return -1;
6193    }
6194
6195    /**
6196     * Perform a reset of the given task, if needed as part of launching it.
6197     * Returns the new HistoryRecord at the top of the task.
6198     */
6199    private final HistoryRecord resetTaskIfNeededLocked(HistoryRecord taskTop,
6200            HistoryRecord newActivity) {
6201        boolean forceReset = (newActivity.info.flags
6202                &ActivityInfo.FLAG_CLEAR_TASK_ON_LAUNCH) != 0;
6203        if (taskTop.task.getInactiveDuration() > ACTIVITY_INACTIVE_RESET_TIME) {
6204            if ((newActivity.info.flags
6205                    &ActivityInfo.FLAG_ALWAYS_RETAIN_TASK_STATE) == 0) {
6206                forceReset = true;
6207            }
6208        }
6209
6210        final TaskRecord task = taskTop.task;
6211
6212        // We are going to move through the history list so that we can look
6213        // at each activity 'target' with 'below' either the interesting
6214        // activity immediately below it in the stack or null.
6215        HistoryRecord target = null;
6216        int targetI = 0;
6217        int taskTopI = -1;
6218        int replyChainEnd = -1;
6219        int lastReparentPos = -1;
6220        for (int i=mHistory.size()-1; i>=-1; i--) {
6221            HistoryRecord below = i >= 0 ? (HistoryRecord)mHistory.get(i) : null;
6222
6223            if (below != null && below.finishing) {
6224                continue;
6225            }
6226            if (target == null) {
6227                target = below;
6228                targetI = i;
6229                // If we were in the middle of a reply chain before this
6230                // task, it doesn't appear like the root of the chain wants
6231                // anything interesting, so drop it.
6232                replyChainEnd = -1;
6233                continue;
6234            }
6235
6236            final int flags = target.info.flags;
6237
6238            final boolean finishOnTaskLaunch =
6239                (flags&ActivityInfo.FLAG_FINISH_ON_TASK_LAUNCH) != 0;
6240            final boolean allowTaskReparenting =
6241                (flags&ActivityInfo.FLAG_ALLOW_TASK_REPARENTING) != 0;
6242
6243            if (target.task == task) {
6244                // We are inside of the task being reset...  we'll either
6245                // finish this activity, push it out for another task,
6246                // or leave it as-is.  We only do this
6247                // for activities that are not the root of the task (since
6248                // if we finish the root, we may no longer have the task!).
6249                if (taskTopI < 0) {
6250                    taskTopI = targetI;
6251                }
6252                if (below != null && below.task == task) {
6253                    final boolean clearWhenTaskReset =
6254                            (target.intent.getFlags()
6255                                    &Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0;
6256                    if (!finishOnTaskLaunch && !clearWhenTaskReset && target.resultTo != null) {
6257                        // If this activity is sending a reply to a previous
6258                        // activity, we can't do anything with it now until
6259                        // we reach the start of the reply chain.
6260                        // XXX note that we are assuming the result is always
6261                        // to the previous activity, which is almost always
6262                        // the case but we really shouldn't count on.
6263                        if (replyChainEnd < 0) {
6264                            replyChainEnd = targetI;
6265                        }
6266                    } else if (!finishOnTaskLaunch && !clearWhenTaskReset && allowTaskReparenting
6267                            && target.taskAffinity != null
6268                            && !target.taskAffinity.equals(task.affinity)) {
6269                        // If this activity has an affinity for another
6270                        // task, then we need to move it out of here.  We will
6271                        // move it as far out of the way as possible, to the
6272                        // bottom of the activity stack.  This also keeps it
6273                        // correctly ordered with any activities we previously
6274                        // moved.
6275                        HistoryRecord p = (HistoryRecord)mHistory.get(0);
6276                        if (target.taskAffinity != null
6277                                && target.taskAffinity.equals(p.task.affinity)) {
6278                            // If the activity currently at the bottom has the
6279                            // same task affinity as the one we are moving,
6280                            // then merge it into the same task.
6281                            target.task = p.task;
6282                            if (DEBUG_TASKS) Log.v(TAG, "Start pushing activity " + target
6283                                    + " out to bottom task " + p.task);
6284                        } else {
6285                            mCurTask++;
6286                            if (mCurTask <= 0) {
6287                                mCurTask = 1;
6288                            }
6289                            target.task = new TaskRecord(mCurTask, target.info, null,
6290                                    (target.info.flags&ActivityInfo.FLAG_CLEAR_TASK_ON_LAUNCH) != 0);
6291                            target.task.affinityIntent = target.intent;
6292                            if (DEBUG_TASKS) Log.v(TAG, "Start pushing activity " + target
6293                                    + " out to new task " + target.task);
6294                        }
6295                        mWindowManager.setAppGroupId(target, task.taskId);
6296                        if (replyChainEnd < 0) {
6297                            replyChainEnd = targetI;
6298                        }
6299                        int dstPos = 0;
6300                        for (int srcPos=targetI; srcPos<=replyChainEnd; srcPos++) {
6301                            p = (HistoryRecord)mHistory.get(srcPos);
6302                            if (p.finishing) {
6303                                continue;
6304                            }
6305                            if (DEBUG_TASKS) Log.v(TAG, "Pushing next activity " + p
6306                                    + " out to target's task " + target.task);
6307                            task.numActivities--;
6308                            p.task = target.task;
6309                            target.task.numActivities++;
6310                            mHistory.remove(srcPos);
6311                            mHistory.add(dstPos, p);
6312                            mWindowManager.moveAppToken(dstPos, p);
6313                            mWindowManager.setAppGroupId(p, p.task.taskId);
6314                            dstPos++;
6315                            if (VALIDATE_TOKENS) {
6316                                mWindowManager.validateAppTokens(mHistory);
6317                            }
6318                            i++;
6319                        }
6320                        if (taskTop == p) {
6321                            taskTop = below;
6322                        }
6323                        if (taskTopI == replyChainEnd) {
6324                            taskTopI = -1;
6325                        }
6326                        replyChainEnd = -1;
6327                        addRecentTask(target.task);
6328                    } else if (forceReset || finishOnTaskLaunch
6329                            || clearWhenTaskReset) {
6330                        // If the activity should just be removed -- either
6331                        // because it asks for it, or the task should be
6332                        // cleared -- then finish it and anything that is
6333                        // part of its reply chain.
6334                        if (clearWhenTaskReset) {
6335                            // In this case, we want to finish this activity
6336                            // and everything above it, so be sneaky and pretend
6337                            // like these are all in the reply chain.
6338                            replyChainEnd = targetI+1;
6339                            while (replyChainEnd < mHistory.size() &&
6340                                    ((HistoryRecord)mHistory.get(
6341                                                replyChainEnd)).task == task) {
6342                                replyChainEnd++;
6343                            }
6344                            replyChainEnd--;
6345                        } else if (replyChainEnd < 0) {
6346                            replyChainEnd = targetI;
6347                        }
6348                        HistoryRecord p = null;
6349                        for (int srcPos=targetI; srcPos<=replyChainEnd; srcPos++) {
6350                            p = (HistoryRecord)mHistory.get(srcPos);
6351                            if (p.finishing) {
6352                                continue;
6353                            }
6354                            if (finishActivityLocked(p, srcPos,
6355                                    Activity.RESULT_CANCELED, null, "reset")) {
6356                                replyChainEnd--;
6357                                srcPos--;
6358                            }
6359                        }
6360                        if (taskTop == p) {
6361                            taskTop = below;
6362                        }
6363                        if (taskTopI == replyChainEnd) {
6364                            taskTopI = -1;
6365                        }
6366                        replyChainEnd = -1;
6367                    } else {
6368                        // If we were in the middle of a chain, well the
6369                        // activity that started it all doesn't want anything
6370                        // special, so leave it all as-is.
6371                        replyChainEnd = -1;
6372                    }
6373                } else {
6374                    // Reached the bottom of the task -- any reply chain
6375                    // should be left as-is.
6376                    replyChainEnd = -1;
6377                }
6378
6379            } else if (target.resultTo != null) {
6380                // If this activity is sending a reply to a previous
6381                // activity, we can't do anything with it now until
6382                // we reach the start of the reply chain.
6383                // XXX note that we are assuming the result is always
6384                // to the previous activity, which is almost always
6385                // the case but we really shouldn't count on.
6386                if (replyChainEnd < 0) {
6387                    replyChainEnd = targetI;
6388                }
6389
6390            } else if (taskTopI >= 0 && allowTaskReparenting
6391                    && task.affinity != null
6392                    && task.affinity.equals(target.taskAffinity)) {
6393                // We are inside of another task...  if this activity has
6394                // an affinity for our task, then either remove it if we are
6395                // clearing or move it over to our task.  Note that
6396                // we currently punt on the case where we are resetting a
6397                // task that is not at the top but who has activities above
6398                // with an affinity to it...  this is really not a normal
6399                // case, and we will need to later pull that task to the front
6400                // and usually at that point we will do the reset and pick
6401                // up those remaining activities.  (This only happens if
6402                // someone starts an activity in a new task from an activity
6403                // in a task that is not currently on top.)
6404                if (forceReset || finishOnTaskLaunch) {
6405                    if (replyChainEnd < 0) {
6406                        replyChainEnd = targetI;
6407                    }
6408                    HistoryRecord p = null;
6409                    for (int srcPos=targetI; srcPos<=replyChainEnd; srcPos++) {
6410                        p = (HistoryRecord)mHistory.get(srcPos);
6411                        if (p.finishing) {
6412                            continue;
6413                        }
6414                        if (finishActivityLocked(p, srcPos,
6415                                Activity.RESULT_CANCELED, null, "reset")) {
6416                            taskTopI--;
6417                            lastReparentPos--;
6418                            replyChainEnd--;
6419                            srcPos--;
6420                        }
6421                    }
6422                    replyChainEnd = -1;
6423                } else {
6424                    if (replyChainEnd < 0) {
6425                        replyChainEnd = targetI;
6426                    }
6427                    for (int srcPos=replyChainEnd; srcPos>=targetI; srcPos--) {
6428                        HistoryRecord p = (HistoryRecord)mHistory.get(srcPos);
6429                        if (p.finishing) {
6430                            continue;
6431                        }
6432                        if (lastReparentPos < 0) {
6433                            lastReparentPos = taskTopI;
6434                            taskTop = p;
6435                        } else {
6436                            lastReparentPos--;
6437                        }
6438                        mHistory.remove(srcPos);
6439                        p.task.numActivities--;
6440                        p.task = task;
6441                        mHistory.add(lastReparentPos, p);
6442                        if (DEBUG_TASKS) Log.v(TAG, "Pulling activity " + p
6443                                + " in to resetting task " + task);
6444                        task.numActivities++;
6445                        mWindowManager.moveAppToken(lastReparentPos, p);
6446                        mWindowManager.setAppGroupId(p, p.task.taskId);
6447                        if (VALIDATE_TOKENS) {
6448                            mWindowManager.validateAppTokens(mHistory);
6449                        }
6450                    }
6451                    replyChainEnd = -1;
6452
6453                    // Now we've moved it in to place...  but what if this is
6454                    // a singleTop activity and we have put it on top of another
6455                    // instance of the same activity?  Then we drop the instance
6456                    // below so it remains singleTop.
6457                    if (target.info.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP) {
6458                        for (int j=lastReparentPos-1; j>=0; j--) {
6459                            HistoryRecord p = (HistoryRecord)mHistory.get(j);
6460                            if (p.finishing) {
6461                                continue;
6462                            }
6463                            if (p.intent.getComponent().equals(target.intent.getComponent())) {
6464                                if (finishActivityLocked(p, j,
6465                                        Activity.RESULT_CANCELED, null, "replace")) {
6466                                    taskTopI--;
6467                                    lastReparentPos--;
6468                                }
6469                            }
6470                        }
6471                    }
6472                }
6473            }
6474
6475            target = below;
6476            targetI = i;
6477        }
6478
6479        return taskTop;
6480    }
6481
6482    /**
6483     * TODO: Add mWatcher hook
6484     */
6485    public void moveTaskToFront(int task) {
6486        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
6487                "moveTaskToFront()");
6488
6489        synchronized(this) {
6490            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
6491                    Binder.getCallingUid(), "Task to front")) {
6492                return;
6493            }
6494            final long origId = Binder.clearCallingIdentity();
6495            try {
6496                int N = mRecentTasks.size();
6497                for (int i=0; i<N; i++) {
6498                    TaskRecord tr = mRecentTasks.get(i);
6499                    if (tr.taskId == task) {
6500                        moveTaskToFrontLocked(tr);
6501                        return;
6502                    }
6503                }
6504                for (int i=mHistory.size()-1; i>=0; i--) {
6505                    HistoryRecord hr = (HistoryRecord)mHistory.get(i);
6506                    if (hr.task.taskId == task) {
6507                        moveTaskToFrontLocked(hr.task);
6508                        return;
6509                    }
6510                }
6511            } finally {
6512                Binder.restoreCallingIdentity(origId);
6513            }
6514        }
6515    }
6516
6517    private final void moveTaskToFrontLocked(TaskRecord tr) {
6518        if (DEBUG_SWITCH) Log.v(TAG, "moveTaskToFront: " + tr);
6519
6520        final int task = tr.taskId;
6521        int top = mHistory.size()-1;
6522
6523        if (top < 0 || ((HistoryRecord)mHistory.get(top)).task.taskId == task) {
6524            // nothing to do!
6525            return;
6526        }
6527
6528        if (DEBUG_TRANSITION) Log.v(TAG,
6529                "Prepare to front transition: task=" + tr);
6530        mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_TASK_TO_FRONT);
6531
6532        ArrayList moved = new ArrayList();
6533
6534        // Applying the affinities may have removed entries from the history,
6535        // so get the size again.
6536        top = mHistory.size()-1;
6537        int pos = top;
6538
6539        // Shift all activities with this task up to the top
6540        // of the stack, keeping them in the same internal order.
6541        while (pos >= 0) {
6542            HistoryRecord r = (HistoryRecord)mHistory.get(pos);
6543            if (localLOGV) Log.v(
6544                TAG, "At " + pos + " ckp " + r.task + ": " + r);
6545            boolean first = true;
6546            if (r.task.taskId == task) {
6547                if (localLOGV) Log.v(TAG, "Removing and adding at " + top);
6548                mHistory.remove(pos);
6549                mHistory.add(top, r);
6550                moved.add(0, r);
6551                top--;
6552                if (first) {
6553                    addRecentTask(r.task);
6554                    first = false;
6555                }
6556            }
6557            pos--;
6558        }
6559
6560        mWindowManager.moveAppTokensToTop(moved);
6561        if (VALIDATE_TOKENS) {
6562            mWindowManager.validateAppTokens(mHistory);
6563        }
6564
6565        finishTaskMove(task);
6566        EventLog.writeEvent(LOG_TASK_TO_FRONT, task);
6567    }
6568
6569    private final void finishTaskMove(int task) {
6570        resumeTopActivityLocked(null);
6571    }
6572
6573    public void moveTaskToBack(int task) {
6574        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
6575                "moveTaskToBack()");
6576
6577        synchronized(this) {
6578            if (mResumedActivity != null && mResumedActivity.task.taskId == task) {
6579                if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
6580                        Binder.getCallingUid(), "Task to back")) {
6581                    return;
6582                }
6583            }
6584            final long origId = Binder.clearCallingIdentity();
6585            moveTaskToBackLocked(task);
6586            Binder.restoreCallingIdentity(origId);
6587        }
6588    }
6589
6590    /**
6591     * Moves an activity, and all of the other activities within the same task, to the bottom
6592     * of the history stack.  The activity's order within the task is unchanged.
6593     *
6594     * @param token A reference to the activity we wish to move
6595     * @param nonRoot If false then this only works if the activity is the root
6596     *                of a task; if true it will work for any activity in a task.
6597     * @return Returns true if the move completed, false if not.
6598     */
6599    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
6600        synchronized(this) {
6601            final long origId = Binder.clearCallingIdentity();
6602            int taskId = getTaskForActivityLocked(token, !nonRoot);
6603            if (taskId >= 0) {
6604                return moveTaskToBackLocked(taskId);
6605            }
6606            Binder.restoreCallingIdentity(origId);
6607        }
6608        return false;
6609    }
6610
6611    /**
6612     * Worker method for rearranging history stack.  Implements the function of moving all
6613     * activities for a specific task (gathering them if disjoint) into a single group at the
6614     * bottom of the stack.
6615     *
6616     * If a watcher is installed, the action is preflighted and the watcher has an opportunity
6617     * to premeptively cancel the move.
6618     *
6619     * @param task The taskId to collect and move to the bottom.
6620     * @return Returns true if the move completed, false if not.
6621     */
6622    private final boolean moveTaskToBackLocked(int task) {
6623        Log.i(TAG, "moveTaskToBack: " + task);
6624
6625        // If we have a watcher, preflight the move before committing to it.  First check
6626        // for *other* available tasks, but if none are available, then try again allowing the
6627        // current task to be selected.
6628        if (mWatcher != null) {
6629            HistoryRecord next = topRunningActivityLocked(null, task);
6630            if (next == null) {
6631                next = topRunningActivityLocked(null, 0);
6632            }
6633            if (next != null) {
6634                // ask watcher if this is allowed
6635                boolean moveOK = true;
6636                try {
6637                    moveOK = mWatcher.activityResuming(next.packageName);
6638                } catch (RemoteException e) {
6639                    mWatcher = null;
6640                }
6641                if (!moveOK) {
6642                    return false;
6643                }
6644            }
6645        }
6646
6647        ArrayList moved = new ArrayList();
6648
6649        if (DEBUG_TRANSITION) Log.v(TAG,
6650                "Prepare to back transition: task=" + task);
6651        mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_TASK_TO_BACK);
6652
6653        final int N = mHistory.size();
6654        int bottom = 0;
6655        int pos = 0;
6656
6657        // Shift all activities with this task down to the bottom
6658        // of the stack, keeping them in the same internal order.
6659        while (pos < N) {
6660            HistoryRecord r = (HistoryRecord)mHistory.get(pos);
6661            if (localLOGV) Log.v(
6662                TAG, "At " + pos + " ckp " + r.task + ": " + r);
6663            if (r.task.taskId == task) {
6664                if (localLOGV) Log.v(TAG, "Removing and adding at " + (N-1));
6665                mHistory.remove(pos);
6666                mHistory.add(bottom, r);
6667                moved.add(r);
6668                bottom++;
6669            }
6670            pos++;
6671        }
6672
6673        mWindowManager.moveAppTokensToBottom(moved);
6674        if (VALIDATE_TOKENS) {
6675            mWindowManager.validateAppTokens(mHistory);
6676        }
6677
6678        finishTaskMove(task);
6679        return true;
6680    }
6681
6682    public void moveTaskBackwards(int task) {
6683        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
6684                "moveTaskBackwards()");
6685
6686        synchronized(this) {
6687            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
6688                    Binder.getCallingUid(), "Task backwards")) {
6689                return;
6690            }
6691            final long origId = Binder.clearCallingIdentity();
6692            moveTaskBackwardsLocked(task);
6693            Binder.restoreCallingIdentity(origId);
6694        }
6695    }
6696
6697    private final void moveTaskBackwardsLocked(int task) {
6698        Log.e(TAG, "moveTaskBackwards not yet implemented!");
6699    }
6700
6701    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
6702        synchronized(this) {
6703            return getTaskForActivityLocked(token, onlyRoot);
6704        }
6705    }
6706
6707    int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
6708        final int N = mHistory.size();
6709        TaskRecord lastTask = null;
6710        for (int i=0; i<N; i++) {
6711            HistoryRecord r = (HistoryRecord)mHistory.get(i);
6712            if (r == token) {
6713                if (!onlyRoot || lastTask != r.task) {
6714                    return r.task.taskId;
6715                }
6716                return -1;
6717            }
6718            lastTask = r.task;
6719        }
6720
6721        return -1;
6722    }
6723
6724    /**
6725     * Returns the top activity in any existing task matching the given
6726     * Intent.  Returns null if no such task is found.
6727     */
6728    private HistoryRecord findTaskLocked(Intent intent, ActivityInfo info) {
6729        ComponentName cls = intent.getComponent();
6730        if (info.targetActivity != null) {
6731            cls = new ComponentName(info.packageName, info.targetActivity);
6732        }
6733
6734        TaskRecord cp = null;
6735
6736        final int N = mHistory.size();
6737        for (int i=(N-1); i>=0; i--) {
6738            HistoryRecord r = (HistoryRecord)mHistory.get(i);
6739            if (!r.finishing && r.task != cp
6740                    && r.launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
6741                cp = r.task;
6742                //Log.i(TAG, "Comparing existing cls=" + r.task.intent.getComponent().flattenToShortString()
6743                //        + "/aff=" + r.task.affinity + " to new cls="
6744                //        + intent.getComponent().flattenToShortString() + "/aff=" + taskAffinity);
6745                if (r.task.affinity != null) {
6746                    if (r.task.affinity.equals(info.taskAffinity)) {
6747                        //Log.i(TAG, "Found matching affinity!");
6748                        return r;
6749                    }
6750                } else if (r.task.intent != null
6751                        && r.task.intent.getComponent().equals(cls)) {
6752                    //Log.i(TAG, "Found matching class!");
6753                    //dump();
6754                    //Log.i(TAG, "For Intent " + intent + " bringing to top: " + r.intent);
6755                    return r;
6756                } else if (r.task.affinityIntent != null
6757                        && r.task.affinityIntent.getComponent().equals(cls)) {
6758                    //Log.i(TAG, "Found matching class!");
6759                    //dump();
6760                    //Log.i(TAG, "For Intent " + intent + " bringing to top: " + r.intent);
6761                    return r;
6762                }
6763            }
6764        }
6765
6766        return null;
6767    }
6768
6769    /**
6770     * Returns the first activity (starting from the top of the stack) that
6771     * is the same as the given activity.  Returns null if no such activity
6772     * is found.
6773     */
6774    private HistoryRecord findActivityLocked(Intent intent, ActivityInfo info) {
6775        ComponentName cls = intent.getComponent();
6776        if (info.targetActivity != null) {
6777            cls = new ComponentName(info.packageName, info.targetActivity);
6778        }
6779
6780        final int N = mHistory.size();
6781        for (int i=(N-1); i>=0; i--) {
6782            HistoryRecord r = (HistoryRecord)mHistory.get(i);
6783            if (!r.finishing) {
6784                if (r.intent.getComponent().equals(cls)) {
6785                    //Log.i(TAG, "Found matching class!");
6786                    //dump();
6787                    //Log.i(TAG, "For Intent " + intent + " bringing to top: " + r.intent);
6788                    return r;
6789                }
6790            }
6791        }
6792
6793        return null;
6794    }
6795
6796    public void finishOtherInstances(IBinder token, ComponentName className) {
6797        synchronized(this) {
6798            final long origId = Binder.clearCallingIdentity();
6799
6800            int N = mHistory.size();
6801            TaskRecord lastTask = null;
6802            for (int i=0; i<N; i++) {
6803                HistoryRecord r = (HistoryRecord)mHistory.get(i);
6804                if (r.realActivity.equals(className)
6805                        && r != token && lastTask != r.task) {
6806                    if (finishActivityLocked(r, i, Activity.RESULT_CANCELED,
6807                            null, "others")) {
6808                        i--;
6809                        N--;
6810                    }
6811                }
6812                lastTask = r.task;
6813            }
6814
6815            Binder.restoreCallingIdentity(origId);
6816        }
6817    }
6818
6819    // =========================================================
6820    // THUMBNAILS
6821    // =========================================================
6822
6823    public void reportThumbnail(IBinder token,
6824            Bitmap thumbnail, CharSequence description) {
6825        //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
6826        final long origId = Binder.clearCallingIdentity();
6827        sendPendingThumbnail(null, token, thumbnail, description, true);
6828        Binder.restoreCallingIdentity(origId);
6829    }
6830
6831    final void sendPendingThumbnail(HistoryRecord r, IBinder token,
6832            Bitmap thumbnail, CharSequence description, boolean always) {
6833        TaskRecord task = null;
6834        ArrayList receivers = null;
6835
6836        //System.out.println("Send pending thumbnail: " + r);
6837
6838        synchronized(this) {
6839            if (r == null) {
6840                int index = indexOfTokenLocked(token, false);
6841                if (index < 0) {
6842                    return;
6843                }
6844                r = (HistoryRecord)mHistory.get(index);
6845            }
6846            if (thumbnail == null) {
6847                thumbnail = r.thumbnail;
6848                description = r.description;
6849            }
6850            if (thumbnail == null && !always) {
6851                // If there is no thumbnail, and this entry is not actually
6852                // going away, then abort for now and pick up the next
6853                // thumbnail we get.
6854                return;
6855            }
6856            task = r.task;
6857
6858            int N = mPendingThumbnails.size();
6859            int i=0;
6860            while (i<N) {
6861                PendingThumbnailsRecord pr =
6862                    (PendingThumbnailsRecord)mPendingThumbnails.get(i);
6863                //System.out.println("Looking in " + pr.pendingRecords);
6864                if (pr.pendingRecords.remove(r)) {
6865                    if (receivers == null) {
6866                        receivers = new ArrayList();
6867                    }
6868                    receivers.add(pr);
6869                    if (pr.pendingRecords.size() == 0) {
6870                        pr.finished = true;
6871                        mPendingThumbnails.remove(i);
6872                        N--;
6873                        continue;
6874                    }
6875                }
6876                i++;
6877            }
6878        }
6879
6880        if (receivers != null) {
6881            final int N = receivers.size();
6882            for (int i=0; i<N; i++) {
6883                try {
6884                    PendingThumbnailsRecord pr =
6885                        (PendingThumbnailsRecord)receivers.get(i);
6886                    pr.receiver.newThumbnail(
6887                        task != null ? task.taskId : -1, thumbnail, description);
6888                    if (pr.finished) {
6889                        pr.receiver.finished();
6890                    }
6891                } catch (Exception e) {
6892                    Log.w(TAG, "Exception thrown when sending thumbnail", e);
6893                }
6894            }
6895        }
6896    }
6897
6898    // =========================================================
6899    // CONTENT PROVIDERS
6900    // =========================================================
6901
6902    private final List generateApplicationProvidersLocked(ProcessRecord app) {
6903        List providers = null;
6904        try {
6905            providers = ActivityThread.getPackageManager().
6906                queryContentProviders(app.processName, app.info.uid,
6907                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
6908        } catch (RemoteException ex) {
6909        }
6910        if (providers != null) {
6911            final int N = providers.size();
6912            for (int i=0; i<N; i++) {
6913                ProviderInfo cpi =
6914                    (ProviderInfo)providers.get(i);
6915                ContentProviderRecord cpr =
6916                    (ContentProviderRecord)mProvidersByClass.get(cpi.name);
6917                if (cpr == null) {
6918                    cpr = new ContentProviderRecord(cpi, app.info);
6919                    mProvidersByClass.put(cpi.name, cpr);
6920                }
6921                app.pubProviders.put(cpi.name, cpr);
6922                app.addPackage(cpi.applicationInfo.packageName);
6923            }
6924        }
6925        return providers;
6926    }
6927
6928    private final String checkContentProviderPermissionLocked(
6929            ProviderInfo cpi, ProcessRecord r, int mode) {
6930        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
6931        final int callingUid = (r != null) ? r.info.uid : Binder.getCallingUid();
6932        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
6933                cpi.exported ? -1 : cpi.applicationInfo.uid)
6934                == PackageManager.PERMISSION_GRANTED
6935                && mode == ParcelFileDescriptor.MODE_READ_ONLY || mode == -1) {
6936            return null;
6937        }
6938        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
6939                cpi.exported ? -1 : cpi.applicationInfo.uid)
6940                == PackageManager.PERMISSION_GRANTED) {
6941            return null;
6942        }
6943        String msg = "Permission Denial: opening provider " + cpi.name
6944                + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
6945                + ", uid=" + callingUid + ") requires "
6946                + cpi.readPermission + " or " + cpi.writePermission;
6947        Log.w(TAG, msg);
6948        return msg;
6949    }
6950
6951    private final ContentProviderHolder getContentProviderImpl(
6952        IApplicationThread caller, String name) {
6953        ContentProviderRecord cpr;
6954        ProviderInfo cpi = null;
6955
6956        synchronized(this) {
6957            ProcessRecord r = null;
6958            if (caller != null) {
6959                r = getRecordForAppLocked(caller);
6960                if (r == null) {
6961                    throw new SecurityException(
6962                            "Unable to find app for caller " + caller
6963                          + " (pid=" + Binder.getCallingPid()
6964                          + ") when getting content provider " + name);
6965                }
6966            }
6967
6968            // First check if this content provider has been published...
6969            cpr = (ContentProviderRecord)mProvidersByName.get(name);
6970            if (cpr != null) {
6971                cpi = cpr.info;
6972                if (checkContentProviderPermissionLocked(cpi, r, -1) != null) {
6973                    return new ContentProviderHolder(cpi,
6974                            cpi.readPermission != null
6975                                    ? cpi.readPermission : cpi.writePermission);
6976                }
6977
6978                if (r != null && cpr.canRunHere(r)) {
6979                    // This provider has been published or is in the process
6980                    // of being published...  but it is also allowed to run
6981                    // in the caller's process, so don't make a connection
6982                    // and just let the caller instantiate its own instance.
6983                    if (cpr.provider != null) {
6984                        // don't give caller the provider object, it needs
6985                        // to make its own.
6986                        cpr = new ContentProviderRecord(cpr);
6987                    }
6988                    return cpr;
6989                }
6990
6991                final long origId = Binder.clearCallingIdentity();
6992
6993                // In this case the provider is a single instance, so we can
6994                // return it right away.
6995                if (r != null) {
6996                    r.conProviders.add(cpr);
6997                    cpr.clients.add(r);
6998                } else {
6999                    cpr.externals++;
7000                }
7001
7002                if (cpr.app != null) {
7003                    updateOomAdjLocked(cpr.app);
7004                }
7005
7006                Binder.restoreCallingIdentity(origId);
7007
7008            } else {
7009                try {
7010                    cpi = ActivityThread.getPackageManager().
7011                        resolveContentProvider(name,
7012                                STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
7013                } catch (RemoteException ex) {
7014                }
7015                if (cpi == null) {
7016                    return null;
7017                }
7018
7019                if (checkContentProviderPermissionLocked(cpi, r, -1) != null) {
7020                    return new ContentProviderHolder(cpi,
7021                            cpi.readPermission != null
7022                                    ? cpi.readPermission : cpi.writePermission);
7023                }
7024
7025                cpr = (ContentProviderRecord)mProvidersByClass.get(cpi.name);
7026                final boolean firstClass = cpr == null;
7027                if (firstClass) {
7028                    try {
7029                        ApplicationInfo ai =
7030                            ActivityThread.getPackageManager().
7031                                getApplicationInfo(
7032                                        cpi.applicationInfo.packageName,
7033                                        STOCK_PM_FLAGS);
7034                        if (ai == null) {
7035                            Log.w(TAG, "No package info for content provider "
7036                                    + cpi.name);
7037                            return null;
7038                        }
7039                        cpr = new ContentProviderRecord(cpi, ai);
7040                    } catch (RemoteException ex) {
7041                        // pm is in same process, this will never happen.
7042                    }
7043                }
7044
7045                if (r != null && cpr.canRunHere(r)) {
7046                    // If this is a multiprocess provider, then just return its
7047                    // info and allow the caller to instantiate it.  Only do
7048                    // this if the provider is the same user as the caller's
7049                    // process, or can run as root (so can be in any process).
7050                    return cpr;
7051                }
7052
7053                if (false) {
7054                    RuntimeException e = new RuntimeException("foo");
7055                    //Log.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.info.uid
7056                    //      + " pruid " + ai.uid + "): " + cpi.className, e);
7057                }
7058
7059                // This is single process, and our app is now connecting to it.
7060                // See if we are already in the process of launching this
7061                // provider.
7062                final int N = mLaunchingProviders.size();
7063                int i;
7064                for (i=0; i<N; i++) {
7065                    if (mLaunchingProviders.get(i) == cpr) {
7066                        break;
7067                    }
7068                    if (false) {
7069                        final ContentProviderRecord rec =
7070                            (ContentProviderRecord)mLaunchingProviders.get(i);
7071                        if (rec.info.name.equals(cpr.info.name)) {
7072                            cpr = rec;
7073                            break;
7074                        }
7075                    }
7076                }
7077
7078                // If the provider is not already being launched, then get it
7079                // started.
7080                if (i >= N) {
7081                    final long origId = Binder.clearCallingIdentity();
7082                    ProcessRecord proc = startProcessLocked(cpi.processName,
7083                            cpr.appInfo, false, 0, "content provider",
7084                            new ComponentName(cpi.applicationInfo.packageName,
7085                                    cpi.name));
7086                    if (proc == null) {
7087                        Log.w(TAG, "Unable to launch app "
7088                                + cpi.applicationInfo.packageName + "/"
7089                                + cpi.applicationInfo.uid + " for provider "
7090                                + name + ": process is bad");
7091                        return null;
7092                    }
7093                    cpr.launchingApp = proc;
7094                    mLaunchingProviders.add(cpr);
7095                    Binder.restoreCallingIdentity(origId);
7096                }
7097
7098                // Make sure the provider is published (the same provider class
7099                // may be published under multiple names).
7100                if (firstClass) {
7101                    mProvidersByClass.put(cpi.name, cpr);
7102                }
7103                mProvidersByName.put(name, cpr);
7104
7105                if (r != null) {
7106                    r.conProviders.add(cpr);
7107                    cpr.clients.add(r);
7108                } else {
7109                    cpr.externals++;
7110                }
7111            }
7112        }
7113
7114        // Wait for the provider to be published...
7115        synchronized (cpr) {
7116            while (cpr.provider == null) {
7117                if (cpr.launchingApp == null) {
7118                    Log.w(TAG, "Unable to launch app "
7119                            + cpi.applicationInfo.packageName + "/"
7120                            + cpi.applicationInfo.uid + " for provider "
7121                            + name + ": launching app became null");
7122                    EventLog.writeEvent(LOG_AM_PROVIDER_LOST_PROCESS,
7123                            cpi.applicationInfo.packageName,
7124                            cpi.applicationInfo.uid, name);
7125                    return null;
7126                }
7127                try {
7128                    cpr.wait();
7129                } catch (InterruptedException ex) {
7130                }
7131            }
7132        }
7133        return cpr;
7134    }
7135
7136    public final ContentProviderHolder getContentProvider(
7137            IApplicationThread caller, String name) {
7138        if (caller == null) {
7139            String msg = "null IApplicationThread when getting content provider "
7140                    + name;
7141            Log.w(TAG, msg);
7142            throw new SecurityException(msg);
7143        }
7144
7145        return getContentProviderImpl(caller, name);
7146    }
7147
7148    private ContentProviderHolder getContentProviderExternal(String name) {
7149        return getContentProviderImpl(null, name);
7150    }
7151
7152    /**
7153     * Drop a content provider from a ProcessRecord's bookkeeping
7154     * @param cpr
7155     */
7156    public void removeContentProvider(IApplicationThread caller, String name) {
7157        synchronized (this) {
7158            ContentProviderRecord cpr = (ContentProviderRecord)mProvidersByName.get(name);
7159            if(cpr == null) {
7160                //remove from mProvidersByClass
7161                if(localLOGV) Log.v(TAG, name+" content provider not found in providers list");
7162                return;
7163            }
7164            final ProcessRecord r = getRecordForAppLocked(caller);
7165            if (r == null) {
7166                throw new SecurityException(
7167                        "Unable to find app for caller " + caller +
7168                        " when removing content provider " + name);
7169            }
7170            //update content provider record entry info
7171            ContentProviderRecord localCpr = (ContentProviderRecord) mProvidersByClass.get(cpr.info.name);
7172            if(localLOGV) Log.v(TAG, "Removing content provider requested by "+
7173                    r.info.processName+" from process "+localCpr.appInfo.processName);
7174            if(localCpr.appInfo.processName ==  r.info.processName) {
7175                //should not happen. taken care of as a local provider
7176                if(localLOGV) Log.v(TAG, "local provider doing nothing Ignoring other names");
7177                return;
7178            } else {
7179                localCpr.clients.remove(r);
7180                r.conProviders.remove(localCpr);
7181            }
7182            updateOomAdjLocked();
7183        }
7184    }
7185
7186    private void removeContentProviderExternal(String name) {
7187        synchronized (this) {
7188            ContentProviderRecord cpr = (ContentProviderRecord)mProvidersByName.get(name);
7189            if(cpr == null) {
7190                //remove from mProvidersByClass
7191                if(localLOGV) Log.v(TAG, name+" content provider not found in providers list");
7192                return;
7193            }
7194
7195            //update content provider record entry info
7196            ContentProviderRecord localCpr = (ContentProviderRecord) mProvidersByClass.get(cpr.info.name);
7197            localCpr.externals--;
7198            if (localCpr.externals < 0) {
7199                Log.e(TAG, "Externals < 0 for content provider " + localCpr);
7200            }
7201            updateOomAdjLocked();
7202        }
7203    }
7204
7205    public final void publishContentProviders(IApplicationThread caller,
7206            List<ContentProviderHolder> providers) {
7207        if (providers == null) {
7208            return;
7209        }
7210
7211        synchronized(this) {
7212            final ProcessRecord r = getRecordForAppLocked(caller);
7213            if (r == null) {
7214                throw new SecurityException(
7215                        "Unable to find app for caller " + caller
7216                      + " (pid=" + Binder.getCallingPid()
7217                      + ") when publishing content providers");
7218            }
7219
7220            final long origId = Binder.clearCallingIdentity();
7221
7222            final int N = providers.size();
7223            for (int i=0; i<N; i++) {
7224                ContentProviderHolder src = providers.get(i);
7225                if (src == null || src.info == null || src.provider == null) {
7226                    continue;
7227                }
7228                ContentProviderRecord dst =
7229                    (ContentProviderRecord)r.pubProviders.get(src.info.name);
7230                if (dst != null) {
7231                    mProvidersByClass.put(dst.info.name, dst);
7232                    String names[] = dst.info.authority.split(";");
7233                    for (int j = 0; j < names.length; j++) {
7234                        mProvidersByName.put(names[j], dst);
7235                    }
7236
7237                    int NL = mLaunchingProviders.size();
7238                    int j;
7239                    for (j=0; j<NL; j++) {
7240                        if (mLaunchingProviders.get(j) == dst) {
7241                            mLaunchingProviders.remove(j);
7242                            j--;
7243                            NL--;
7244                        }
7245                    }
7246                    synchronized (dst) {
7247                        dst.provider = src.provider;
7248                        dst.app = r;
7249                        dst.notifyAll();
7250                    }
7251                    updateOomAdjLocked(r);
7252                }
7253            }
7254
7255            Binder.restoreCallingIdentity(origId);
7256        }
7257    }
7258
7259    public static final void installSystemProviders() {
7260        ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
7261        List providers = mSelf.generateApplicationProvidersLocked(app);
7262        mSystemThread.installSystemProviders(providers);
7263    }
7264
7265    // =========================================================
7266    // GLOBAL MANAGEMENT
7267    // =========================================================
7268
7269    final ProcessRecord newProcessRecordLocked(IApplicationThread thread,
7270            ApplicationInfo info, String customProcess) {
7271        String proc = customProcess != null ? customProcess : info.processName;
7272        BatteryStatsImpl.Uid.Proc ps = null;
7273        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
7274        synchronized (stats) {
7275            ps = stats.getProcessStatsLocked(info.uid, proc);
7276        }
7277        return new ProcessRecord(ps, thread, info, proc);
7278    }
7279
7280    final ProcessRecord addAppLocked(ApplicationInfo info) {
7281        ProcessRecord app = getProcessRecordLocked(info.processName, info.uid);
7282
7283        if (app == null) {
7284            app = newProcessRecordLocked(null, info, null);
7285            mProcessNames.put(info.processName, info.uid, app);
7286            updateLRUListLocked(app, true);
7287        }
7288
7289        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
7290                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
7291            app.persistent = true;
7292            app.maxAdj = CORE_SERVER_ADJ;
7293        }
7294        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
7295            mPersistentStartingProcesses.add(app);
7296            startProcessLocked(app, "added application", app.processName);
7297        }
7298
7299        return app;
7300    }
7301
7302    public void unhandledBack() {
7303        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
7304                "unhandledBack()");
7305
7306        synchronized(this) {
7307            int count = mHistory.size();
7308            if (Config.LOGD) Log.d(
7309                TAG, "Performing unhandledBack(): stack size = " + count);
7310            if (count > 1) {
7311                final long origId = Binder.clearCallingIdentity();
7312                finishActivityLocked((HistoryRecord)mHistory.get(count-1),
7313                        count-1, Activity.RESULT_CANCELED, null, "unhandled-back");
7314                Binder.restoreCallingIdentity(origId);
7315            }
7316        }
7317    }
7318
7319    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
7320        String name = uri.getAuthority();
7321        ContentProviderHolder cph = getContentProviderExternal(name);
7322        ParcelFileDescriptor pfd = null;
7323        if (cph != null) {
7324            // We record the binder invoker's uid in thread-local storage before
7325            // going to the content provider to open the file.  Later, in the code
7326            // that handles all permissions checks, we look for this uid and use
7327            // that rather than the Activity Manager's own uid.  The effect is that
7328            // we do the check against the caller's permissions even though it looks
7329            // to the content provider like the Activity Manager itself is making
7330            // the request.
7331            sCallerIdentity.set(new Identity(
7332                    Binder.getCallingPid(), Binder.getCallingUid()));
7333            try {
7334                pfd = cph.provider.openFile(uri, "r");
7335            } catch (FileNotFoundException e) {
7336                // do nothing; pfd will be returned null
7337            } finally {
7338                // Ensure that whatever happens, we clean up the identity state
7339                sCallerIdentity.remove();
7340            }
7341
7342            // We've got the fd now, so we're done with the provider.
7343            removeContentProviderExternal(name);
7344        } else {
7345            Log.d(TAG, "Failed to get provider for authority '" + name + "'");
7346        }
7347        return pfd;
7348    }
7349
7350    public void goingToSleep() {
7351        synchronized(this) {
7352            mSleeping = true;
7353            mWindowManager.setEventDispatching(false);
7354
7355            if (mResumedActivity != null) {
7356                pauseIfSleepingLocked();
7357            } else {
7358                Log.w(TAG, "goingToSleep with no resumed activity!");
7359            }
7360        }
7361    }
7362
7363    public boolean shutdown(int timeout) {
7364        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
7365                != PackageManager.PERMISSION_GRANTED) {
7366            throw new SecurityException("Requires permission "
7367                    + android.Manifest.permission.SHUTDOWN);
7368        }
7369
7370        boolean timedout = false;
7371
7372        synchronized(this) {
7373            mShuttingDown = true;
7374            mWindowManager.setEventDispatching(false);
7375
7376            if (mResumedActivity != null) {
7377                pauseIfSleepingLocked();
7378                final long endTime = System.currentTimeMillis() + timeout;
7379                while (mResumedActivity != null || mPausingActivity != null) {
7380                    long delay = endTime - System.currentTimeMillis();
7381                    if (delay <= 0) {
7382                        Log.w(TAG, "Activity manager shutdown timed out");
7383                        timedout = true;
7384                        break;
7385                    }
7386                    try {
7387                        this.wait();
7388                    } catch (InterruptedException e) {
7389                    }
7390                }
7391            }
7392        }
7393
7394        mUsageStatsService.shutdown();
7395        mBatteryStatsService.shutdown();
7396
7397        return timedout;
7398    }
7399
7400    void pauseIfSleepingLocked() {
7401        if (mSleeping || mShuttingDown) {
7402            if (!mGoingToSleep.isHeld()) {
7403                mGoingToSleep.acquire();
7404                if (mLaunchingActivity.isHeld()) {
7405                    mLaunchingActivity.release();
7406                    mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
7407                }
7408            }
7409
7410            // If we are not currently pausing an activity, get the current
7411            // one to pause.  If we are pausing one, we will just let that stuff
7412            // run and release the wake lock when all done.
7413            if (mPausingActivity == null) {
7414                if (DEBUG_PAUSE) Log.v(TAG, "Sleep needs to pause...");
7415                if (DEBUG_USER_LEAVING) Log.v(TAG, "Sleep => pause with userLeaving=false");
7416                startPausingLocked(false, true);
7417            }
7418        }
7419    }
7420
7421    public void wakingUp() {
7422        synchronized(this) {
7423            if (mGoingToSleep.isHeld()) {
7424                mGoingToSleep.release();
7425            }
7426            mWindowManager.setEventDispatching(true);
7427            mSleeping = false;
7428            resumeTopActivityLocked(null);
7429        }
7430    }
7431
7432    public void stopAppSwitches() {
7433        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
7434                != PackageManager.PERMISSION_GRANTED) {
7435            throw new SecurityException("Requires permission "
7436                    + android.Manifest.permission.STOP_APP_SWITCHES);
7437        }
7438
7439        synchronized(this) {
7440            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
7441                    + APP_SWITCH_DELAY_TIME;
7442            mDidAppSwitch = false;
7443            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
7444            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
7445            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
7446        }
7447    }
7448
7449    public void resumeAppSwitches() {
7450        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
7451                != PackageManager.PERMISSION_GRANTED) {
7452            throw new SecurityException("Requires permission "
7453                    + android.Manifest.permission.STOP_APP_SWITCHES);
7454        }
7455
7456        synchronized(this) {
7457            // Note that we don't execute any pending app switches... we will
7458            // let those wait until either the timeout, or the next start
7459            // activity request.
7460            mAppSwitchesAllowedTime = 0;
7461        }
7462    }
7463
7464    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
7465            String name) {
7466        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
7467            return true;
7468        }
7469
7470        final int perm = checkComponentPermission(
7471                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
7472                callingUid, -1);
7473        if (perm == PackageManager.PERMISSION_GRANTED) {
7474            return true;
7475        }
7476
7477        Log.w(TAG, name + " request from " + callingUid + " stopped");
7478        return false;
7479    }
7480
7481    public void setDebugApp(String packageName, boolean waitForDebugger,
7482            boolean persistent) {
7483        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
7484                "setDebugApp()");
7485
7486        // Note that this is not really thread safe if there are multiple
7487        // callers into it at the same time, but that's not a situation we
7488        // care about.
7489        if (persistent) {
7490            final ContentResolver resolver = mContext.getContentResolver();
7491            Settings.System.putString(
7492                resolver, Settings.System.DEBUG_APP,
7493                packageName);
7494            Settings.System.putInt(
7495                resolver, Settings.System.WAIT_FOR_DEBUGGER,
7496                waitForDebugger ? 1 : 0);
7497        }
7498
7499        synchronized (this) {
7500            if (!persistent) {
7501                mOrigDebugApp = mDebugApp;
7502                mOrigWaitForDebugger = mWaitForDebugger;
7503            }
7504            mDebugApp = packageName;
7505            mWaitForDebugger = waitForDebugger;
7506            mDebugTransient = !persistent;
7507            if (packageName != null) {
7508                final long origId = Binder.clearCallingIdentity();
7509                uninstallPackageLocked(packageName, -1, false);
7510                Binder.restoreCallingIdentity(origId);
7511            }
7512        }
7513    }
7514
7515    public void setAlwaysFinish(boolean enabled) {
7516        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
7517                "setAlwaysFinish()");
7518
7519        Settings.System.putInt(
7520                mContext.getContentResolver(),
7521                Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
7522
7523        synchronized (this) {
7524            mAlwaysFinishActivities = enabled;
7525        }
7526    }
7527
7528    public void setActivityWatcher(IActivityWatcher watcher) {
7529        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
7530                "setActivityWatcher()");
7531        synchronized (this) {
7532            mWatcher = watcher;
7533        }
7534    }
7535
7536    public final void enterSafeMode() {
7537        synchronized(this) {
7538            // It only makes sense to do this before the system is ready
7539            // and started launching other packages.
7540            if (!mSystemReady) {
7541                try {
7542                    ActivityThread.getPackageManager().enterSafeMode();
7543                } catch (RemoteException e) {
7544                }
7545
7546                View v = LayoutInflater.from(mContext).inflate(
7547                        com.android.internal.R.layout.safe_mode, null);
7548                WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
7549                lp.type = WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY;
7550                lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
7551                lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
7552                lp.gravity = Gravity.BOTTOM | Gravity.LEFT;
7553                lp.format = v.getBackground().getOpacity();
7554                lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
7555                        | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
7556                ((WindowManager)mContext.getSystemService(
7557                        Context.WINDOW_SERVICE)).addView(v, lp);
7558            }
7559        }
7560    }
7561
7562    public void noteWakeupAlarm(IIntentSender sender) {
7563        if (!(sender instanceof PendingIntentRecord)) {
7564            return;
7565        }
7566        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
7567        synchronized (stats) {
7568            if (mBatteryStatsService.isOnBattery()) {
7569                mBatteryStatsService.enforceCallingPermission();
7570                PendingIntentRecord rec = (PendingIntentRecord)sender;
7571                int MY_UID = Binder.getCallingUid();
7572                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
7573                BatteryStatsImpl.Uid.Pkg pkg =
7574                    stats.getPackageStatsLocked(uid, rec.key.packageName);
7575                pkg.incWakeupsLocked();
7576            }
7577        }
7578    }
7579
7580    public boolean killPidsForMemory(int[] pids) {
7581        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7582            throw new SecurityException("killPidsForMemory only available to the system");
7583        }
7584
7585        // XXX Note: don't acquire main activity lock here, because the window
7586        // manager calls in with its locks held.
7587
7588        boolean killed = false;
7589        synchronized (mPidsSelfLocked) {
7590            int[] types = new int[pids.length];
7591            int worstType = 0;
7592            for (int i=0; i<pids.length; i++) {
7593                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
7594                if (proc != null) {
7595                    int type = proc.setAdj;
7596                    types[i] = type;
7597                    if (type > worstType) {
7598                        worstType = type;
7599                    }
7600                }
7601            }
7602
7603            // If the worse oom_adj is somewhere in the hidden proc LRU range,
7604            // then constrain it so we will kill all hidden procs.
7605            if (worstType < EMPTY_APP_ADJ && worstType > HIDDEN_APP_MIN_ADJ) {
7606                worstType = HIDDEN_APP_MIN_ADJ;
7607            }
7608            Log.w(TAG, "Killing processes for memory at adjustment " + worstType);
7609            for (int i=0; i<pids.length; i++) {
7610                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
7611                if (proc == null) {
7612                    continue;
7613                }
7614                int adj = proc.setAdj;
7615                if (adj >= worstType) {
7616                    Log.w(TAG, "Killing for memory: " + proc + " (adj "
7617                            + adj + ")");
7618                    EventLog.writeEvent(LOG_AM_KILL_FOR_MEMORY, proc.pid,
7619                            proc.processName, adj);
7620                    killed = true;
7621                    Process.killProcess(pids[i]);
7622                }
7623            }
7624        }
7625        return killed;
7626    }
7627
7628    public void reportPss(IApplicationThread caller, int pss) {
7629        Watchdog.PssRequestor req;
7630        String name;
7631        ProcessRecord callerApp;
7632        synchronized (this) {
7633            if (caller == null) {
7634                return;
7635            }
7636            callerApp = getRecordForAppLocked(caller);
7637            if (callerApp == null) {
7638                return;
7639            }
7640            callerApp.lastPss = pss;
7641            req = callerApp;
7642            name = callerApp.processName;
7643        }
7644        Watchdog.getInstance().reportPss(req, name, pss);
7645        if (!callerApp.persistent) {
7646            removeRequestedPss(callerApp);
7647        }
7648    }
7649
7650    public void requestPss(Runnable completeCallback) {
7651        ArrayList<ProcessRecord> procs;
7652        synchronized (this) {
7653            mRequestPssCallback = completeCallback;
7654            mRequestPssList.clear();
7655            for (int i=mLRUProcesses.size()-1; i>=0; i--) {
7656                ProcessRecord proc = mLRUProcesses.get(i);
7657                if (!proc.persistent) {
7658                    mRequestPssList.add(proc);
7659                }
7660            }
7661            procs = new ArrayList<ProcessRecord>(mRequestPssList);
7662        }
7663
7664        int oldPri = Process.getThreadPriority(Process.myTid());
7665        Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
7666        for (int i=procs.size()-1; i>=0; i--) {
7667            ProcessRecord proc = procs.get(i);
7668            proc.lastPss = 0;
7669            proc.requestPss();
7670        }
7671        Process.setThreadPriority(oldPri);
7672    }
7673
7674    void removeRequestedPss(ProcessRecord proc) {
7675        Runnable callback = null;
7676        synchronized (this) {
7677            if (mRequestPssList.remove(proc)) {
7678                if (mRequestPssList.size() == 0) {
7679                    callback = mRequestPssCallback;
7680                    mRequestPssCallback = null;
7681                }
7682            }
7683        }
7684
7685        if (callback != null) {
7686            callback.run();
7687        }
7688    }
7689
7690    public void collectPss(Watchdog.PssStats stats) {
7691        stats.mEmptyPss = 0;
7692        stats.mEmptyCount = 0;
7693        stats.mBackgroundPss = 0;
7694        stats.mBackgroundCount = 0;
7695        stats.mServicePss = 0;
7696        stats.mServiceCount = 0;
7697        stats.mVisiblePss = 0;
7698        stats.mVisibleCount = 0;
7699        stats.mForegroundPss = 0;
7700        stats.mForegroundCount = 0;
7701        stats.mNoPssCount = 0;
7702        synchronized (this) {
7703            int i;
7704            int NPD = mProcDeaths.length < stats.mProcDeaths.length
7705                    ? mProcDeaths.length : stats.mProcDeaths.length;
7706            int aggr = 0;
7707            for (i=0; i<NPD; i++) {
7708                aggr += mProcDeaths[i];
7709                stats.mProcDeaths[i] = aggr;
7710            }
7711            while (i<stats.mProcDeaths.length) {
7712                stats.mProcDeaths[i] = 0;
7713                i++;
7714            }
7715
7716            for (i=mLRUProcesses.size()-1; i>=0; i--) {
7717                ProcessRecord proc = mLRUProcesses.get(i);
7718                if (proc.persistent) {
7719                    continue;
7720                }
7721                //Log.i(TAG, "Proc " + proc + ": pss=" + proc.lastPss);
7722                if (proc.lastPss == 0) {
7723                    stats.mNoPssCount++;
7724                    continue;
7725                }
7726                if (proc.setAdj == EMPTY_APP_ADJ) {
7727                    stats.mEmptyPss += proc.lastPss;
7728                    stats.mEmptyCount++;
7729                } else if (proc.setAdj == CONTENT_PROVIDER_ADJ) {
7730                    stats.mEmptyPss += proc.lastPss;
7731                    stats.mEmptyCount++;
7732                } else if (proc.setAdj >= HIDDEN_APP_MIN_ADJ) {
7733                    stats.mBackgroundPss += proc.lastPss;
7734                    stats.mBackgroundCount++;
7735                } else if (proc.setAdj >= VISIBLE_APP_ADJ) {
7736                    stats.mVisiblePss += proc.lastPss;
7737                    stats.mVisibleCount++;
7738                } else {
7739                    stats.mForegroundPss += proc.lastPss;
7740                    stats.mForegroundCount++;
7741                }
7742            }
7743        }
7744    }
7745
7746    public final void startRunning(String pkg, String cls, String action,
7747            String data) {
7748        synchronized(this) {
7749            if (mStartRunning) {
7750                return;
7751            }
7752            mStartRunning = true;
7753            mTopComponent = pkg != null && cls != null
7754                    ? new ComponentName(pkg, cls) : null;
7755            mTopAction = action != null ? action : Intent.ACTION_MAIN;
7756            mTopData = data;
7757            if (!mSystemReady) {
7758                return;
7759            }
7760        }
7761
7762        systemReady();
7763    }
7764
7765    private void retrieveSettings() {
7766        final ContentResolver resolver = mContext.getContentResolver();
7767        String debugApp = Settings.System.getString(
7768            resolver, Settings.System.DEBUG_APP);
7769        boolean waitForDebugger = Settings.System.getInt(
7770            resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0;
7771        boolean alwaysFinishActivities = Settings.System.getInt(
7772            resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
7773
7774        Configuration configuration = new Configuration();
7775        Settings.System.getConfiguration(resolver, configuration);
7776
7777        synchronized (this) {
7778            mDebugApp = mOrigDebugApp = debugApp;
7779            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
7780            mAlwaysFinishActivities = alwaysFinishActivities;
7781            // This happens before any activities are started, so we can
7782            // change mConfiguration in-place.
7783            mConfiguration.updateFrom(configuration);
7784        }
7785    }
7786
7787    public boolean testIsSystemReady() {
7788        // no need to synchronize(this) just to read & return the value
7789        return mSystemReady;
7790    }
7791
7792    public void systemReady() {
7793        // In the simulator, startRunning will never have been called, which
7794        // normally sets a few crucial variables. Do it here instead.
7795        if (!Process.supportsProcesses()) {
7796            mStartRunning = true;
7797            mTopAction = Intent.ACTION_MAIN;
7798        }
7799
7800        synchronized(this) {
7801            if (mSystemReady) {
7802                return;
7803            }
7804            mSystemReady = true;
7805            if (!mStartRunning) {
7806                return;
7807            }
7808        }
7809
7810        if (Config.LOGD) Log.d(TAG, "Start running!");
7811        EventLog.writeEvent(LOG_BOOT_PROGRESS_AMS_READY,
7812            SystemClock.uptimeMillis());
7813
7814        synchronized(this) {
7815            if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
7816                ResolveInfo ri = mContext.getPackageManager()
7817                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
7818                                STOCK_PM_FLAGS);
7819                CharSequence errorMsg = null;
7820                if (ri != null) {
7821                    ActivityInfo ai = ri.activityInfo;
7822                    ApplicationInfo app = ai.applicationInfo;
7823                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
7824                        mTopAction = Intent.ACTION_FACTORY_TEST;
7825                        mTopData = null;
7826                        mTopComponent = new ComponentName(app.packageName,
7827                                ai.name);
7828                    } else {
7829                        errorMsg = mContext.getResources().getText(
7830                                com.android.internal.R.string.factorytest_not_system);
7831                    }
7832                } else {
7833                    errorMsg = mContext.getResources().getText(
7834                            com.android.internal.R.string.factorytest_no_action);
7835                }
7836                if (errorMsg != null) {
7837                    mTopAction = null;
7838                    mTopData = null;
7839                    mTopComponent = null;
7840                    Message msg = Message.obtain();
7841                    msg.what = SHOW_FACTORY_ERROR_MSG;
7842                    msg.getData().putCharSequence("msg", errorMsg);
7843                    mHandler.sendMessage(msg);
7844                }
7845            }
7846        }
7847
7848        retrieveSettings();
7849
7850        synchronized (this) {
7851            if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
7852                try {
7853                    List apps = ActivityThread.getPackageManager().
7854                        getPersistentApplications(STOCK_PM_FLAGS);
7855                    if (apps != null) {
7856                        int N = apps.size();
7857                        int i;
7858                        for (i=0; i<N; i++) {
7859                            ApplicationInfo info
7860                                = (ApplicationInfo)apps.get(i);
7861                            if (info != null &&
7862                                    !info.packageName.equals("android")) {
7863                                addAppLocked(info);
7864                            }
7865                        }
7866                    }
7867                } catch (RemoteException ex) {
7868                    // pm is in same process, this will never happen.
7869                }
7870            }
7871
7872            try {
7873                if (ActivityThread.getPackageManager().hasSystemUidErrors()) {
7874                    Message msg = Message.obtain();
7875                    msg.what = SHOW_UID_ERROR_MSG;
7876                    mHandler.sendMessage(msg);
7877                }
7878            } catch (RemoteException e) {
7879            }
7880
7881            // Start up initial activity.
7882            mBooting = true;
7883            resumeTopActivityLocked(null);
7884        }
7885    }
7886
7887    boolean makeAppCrashingLocked(ProcessRecord app,
7888            String tag, String shortMsg, String longMsg, byte[] crashData) {
7889        app.crashing = true;
7890        app.crashingReport = generateProcessError(app,
7891                ActivityManager.ProcessErrorStateInfo.CRASHED, tag, shortMsg, longMsg, crashData);
7892        startAppProblemLocked(app);
7893        app.stopFreezingAllLocked();
7894        return handleAppCrashLocked(app);
7895    }
7896
7897    private ComponentName getErrorReportReceiver(ProcessRecord app) {
7898        IPackageManager pm = ActivityThread.getPackageManager();
7899        try {
7900            // was an installer package name specified when this app was
7901            // installed?
7902            String installerPackageName = pm.getInstallerPackageName(app.info.packageName);
7903            if (installerPackageName == null) {
7904                return null;
7905            }
7906
7907            // is there an Activity in this package that handles ACTION_APP_ERROR?
7908            Intent intent = new Intent(Intent.ACTION_APP_ERROR);
7909            ResolveInfo info = pm.resolveIntentForPackage(intent, null, 0, installerPackageName);
7910            if (info == null || info.activityInfo == null) {
7911                return null;
7912            }
7913
7914            return new ComponentName(installerPackageName, info.activityInfo.name);
7915        } catch (RemoteException e) {
7916            // will return null and no error report will be delivered
7917        }
7918        return null;
7919    }
7920
7921    void makeAppNotRespondingLocked(ProcessRecord app,
7922            String tag, String shortMsg, String longMsg, byte[] crashData) {
7923        app.notResponding = true;
7924        app.notRespondingReport = generateProcessError(app,
7925                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, tag, shortMsg, longMsg,
7926                crashData);
7927        startAppProblemLocked(app);
7928        app.stopFreezingAllLocked();
7929    }
7930
7931    /**
7932     * Generate a process error record, suitable for attachment to a ProcessRecord.
7933     *
7934     * @param app The ProcessRecord in which the error occurred.
7935     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
7936     *                      ActivityManager.AppErrorStateInfo
7937     * @param tag The tag that was passed into handleApplicationError().  Typically the classname.
7938     * @param shortMsg Short message describing the crash.
7939     * @param longMsg Long message describing the crash.
7940     * @param crashData Raw data passed into handleApplicationError().  Typically a stack trace.
7941     *
7942     * @return Returns a fully-formed AppErrorStateInfo record.
7943     */
7944    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
7945            int condition, String tag, String shortMsg, String longMsg, byte[] crashData) {
7946        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
7947
7948        report.condition = condition;
7949        report.processName = app.processName;
7950        report.pid = app.pid;
7951        report.uid = app.info.uid;
7952        report.tag = tag;
7953        report.shortMsg = shortMsg;
7954        report.longMsg = longMsg;
7955        report.crashData = crashData;
7956
7957        return report;
7958    }
7959
7960    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog,
7961            boolean crashed) {
7962        synchronized (this) {
7963            app.crashing = false;
7964            app.crashingReport = null;
7965            app.notResponding = false;
7966            app.notRespondingReport = null;
7967            if (app.anrDialog == fromDialog) {
7968                app.anrDialog = null;
7969            }
7970            if (app.waitDialog == fromDialog) {
7971                app.waitDialog = null;
7972            }
7973            if (app.pid > 0 && app.pid != MY_PID) {
7974                if (crashed) {
7975                    handleAppCrashLocked(app);
7976                }
7977                Log.i(ActivityManagerService.TAG, "Killing process "
7978                        + app.processName
7979                        + " (pid=" + app.pid + ") at user's request");
7980                Process.killProcess(app.pid);
7981            }
7982
7983        }
7984    }
7985
7986    boolean handleAppCrashLocked(ProcessRecord app) {
7987        long now = SystemClock.uptimeMillis();
7988
7989        Long crashTime = mProcessCrashTimes.get(app.info.processName,
7990                app.info.uid);
7991        if (crashTime != null && now < crashTime+MIN_CRASH_INTERVAL) {
7992            // This process loses!
7993            Log.w(TAG, "Process " + app.info.processName
7994                    + " has crashed too many times: killing!");
7995            EventLog.writeEvent(LOG_AM_PROCESS_CRASHED_TOO_MUCH,
7996                    app.info.processName, app.info.uid);
7997            killServicesLocked(app, false);
7998            for (int i=mHistory.size()-1; i>=0; i--) {
7999                HistoryRecord r = (HistoryRecord)mHistory.get(i);
8000                if (r.app == app) {
8001                    if (Config.LOGD) Log.d(
8002                        TAG, "  Force finishing activity "
8003                        + r.intent.getComponent().flattenToShortString());
8004                    finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed");
8005                }
8006            }
8007            if (!app.persistent) {
8008                // We don't want to start this process again until the user
8009                // explicitly does so...  but for persistent process, we really
8010                // need to keep it running.  If a persistent process is actually
8011                // repeatedly crashing, then badness for everyone.
8012                EventLog.writeEvent(LOG_AM_PROCESS_BAD, app.info.uid,
8013                        app.info.processName);
8014                mBadProcesses.put(app.info.processName, app.info.uid, now);
8015                app.bad = true;
8016                mProcessCrashTimes.remove(app.info.processName, app.info.uid);
8017                app.removed = true;
8018                removeProcessLocked(app, false);
8019                return false;
8020            }
8021        }
8022
8023        // Bump up the crash count of any services currently running in the proc.
8024        if (app.services.size() != 0) {
8025            // Any services running in the application need to be placed
8026            // back in the pending list.
8027            Iterator it = app.services.iterator();
8028            while (it.hasNext()) {
8029                ServiceRecord sr = (ServiceRecord)it.next();
8030                sr.crashCount++;
8031            }
8032        }
8033
8034        mProcessCrashTimes.put(app.info.processName, app.info.uid, now);
8035        return true;
8036    }
8037
8038    void startAppProblemLocked(ProcessRecord app) {
8039        app.errorReportReceiver = getErrorReportReceiver(app);
8040        skipCurrentReceiverLocked(app);
8041    }
8042
8043    void skipCurrentReceiverLocked(ProcessRecord app) {
8044        boolean reschedule = false;
8045        BroadcastRecord r = app.curReceiver;
8046        if (r != null) {
8047            // The current broadcast is waiting for this app's receiver
8048            // to be finished.  Looks like that's not going to happen, so
8049            // let the broadcast continue.
8050            logBroadcastReceiverDiscard(r);
8051            finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
8052                    r.resultExtras, r.resultAbort, true);
8053            reschedule = true;
8054        }
8055        r = mPendingBroadcast;
8056        if (r != null && r.curApp == app) {
8057            if (DEBUG_BROADCAST) Log.v(TAG,
8058                    "skip & discard pending app " + r);
8059            logBroadcastReceiverDiscard(r);
8060            finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
8061                    r.resultExtras, r.resultAbort, true);
8062            reschedule = true;
8063        }
8064        if (reschedule) {
8065            scheduleBroadcastsLocked();
8066        }
8067    }
8068
8069    public int handleApplicationError(IBinder app, int flags,
8070            String tag, String shortMsg, String longMsg, byte[] crashData) {
8071        AppErrorResult result = new AppErrorResult();
8072        ProcessRecord r = null;
8073        synchronized (this) {
8074            if (app != null) {
8075                for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
8076                    final int NA = apps.size();
8077                    for (int ia=0; ia<NA; ia++) {
8078                        ProcessRecord p = apps.valueAt(ia);
8079                        if (p.thread != null && p.thread.asBinder() == app) {
8080                            r = p;
8081                            break;
8082                        }
8083                    }
8084                }
8085            }
8086
8087            if (r != null) {
8088                // The application has crashed. Send the SIGQUIT to the process so
8089                // that it can dump its state.
8090                Process.sendSignal(r.pid, Process.SIGNAL_QUIT);
8091                //Log.i(TAG, "Current system threads:");
8092                //Process.sendSignal(MY_PID, Process.SIGNAL_QUIT);
8093            }
8094
8095            if (mWatcher != null) {
8096                try {
8097                    String name = r != null ? r.processName : null;
8098                    int pid = r != null ? r.pid : Binder.getCallingPid();
8099                    if (!mWatcher.appCrashed(name, pid,
8100                            shortMsg, longMsg, crashData)) {
8101                        Log.w(TAG, "Force-killing crashed app " + name
8102                                + " at watcher's request");
8103                        Process.killProcess(pid);
8104                        return 0;
8105                    }
8106                } catch (RemoteException e) {
8107                    mWatcher = null;
8108                }
8109            }
8110
8111            final long origId = Binder.clearCallingIdentity();
8112
8113            // If this process is running instrumentation, finish it.
8114            if (r != null && r.instrumentationClass != null) {
8115                Log.w(TAG, "Error in app " + r.processName
8116                      + " running instrumentation " + r.instrumentationClass + ":");
8117                if (shortMsg != null) Log.w(TAG, "  " + shortMsg);
8118                if (longMsg != null) Log.w(TAG, "  " + longMsg);
8119                Bundle info = new Bundle();
8120                info.putString("shortMsg", shortMsg);
8121                info.putString("longMsg", longMsg);
8122                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
8123                Binder.restoreCallingIdentity(origId);
8124                return 0;
8125            }
8126
8127            if (r != null) {
8128                if (!makeAppCrashingLocked(r, tag, shortMsg, longMsg, crashData)) {
8129                    return 0;
8130                }
8131            } else {
8132                Log.w(TAG, "Some application object " + app + " tag " + tag
8133                        + " has crashed, but I don't know who it is.");
8134                Log.w(TAG, "ShortMsg:" + shortMsg);
8135                Log.w(TAG, "LongMsg:" + longMsg);
8136                Binder.restoreCallingIdentity(origId);
8137                return 0;
8138            }
8139
8140            Message msg = Message.obtain();
8141            msg.what = SHOW_ERROR_MSG;
8142            HashMap data = new HashMap();
8143            data.put("result", result);
8144            data.put("app", r);
8145            data.put("flags", flags);
8146            data.put("shortMsg", shortMsg);
8147            data.put("longMsg", longMsg);
8148            if (r != null && (r.info.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
8149                // For system processes, submit crash data to the server.
8150                data.put("crashData", crashData);
8151            }
8152            msg.obj = data;
8153            mHandler.sendMessage(msg);
8154
8155            Binder.restoreCallingIdentity(origId);
8156        }
8157
8158        int res = result.get();
8159
8160        Intent appErrorIntent = null;
8161        synchronized (this) {
8162            if (r != null) {
8163                mProcessCrashTimes.put(r.info.processName, r.info.uid,
8164                        SystemClock.uptimeMillis());
8165            }
8166            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
8167                appErrorIntent = createAppErrorIntentLocked(r);
8168                res = AppErrorDialog.FORCE_QUIT;
8169            }
8170        }
8171
8172        if (appErrorIntent != null) {
8173            try {
8174                mContext.startActivity(appErrorIntent);
8175            } catch (ActivityNotFoundException e) {
8176                Log.w(TAG, "bug report receiver dissappeared", e);
8177            }
8178        }
8179
8180        return res;
8181    }
8182
8183    Intent createAppErrorIntentLocked(ProcessRecord r) {
8184        ApplicationErrorReport report = createAppErrorReportLocked(r);
8185        if (report == null) {
8186            return null;
8187        }
8188        Intent result = new Intent(Intent.ACTION_APP_ERROR);
8189        result.setComponent(r.errorReportReceiver);
8190        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
8191        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8192        return result;
8193    }
8194
8195    ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r) {
8196        if (r.errorReportReceiver == null) {
8197            return null;
8198        }
8199
8200        if (!r.crashing && !r.notResponding) {
8201            return null;
8202        }
8203
8204        try {
8205            ApplicationErrorReport report = new ApplicationErrorReport();
8206            report.packageName = r.info.packageName;
8207            report.installerPackageName = r.errorReportReceiver.getPackageName();
8208            report.processName = r.processName;
8209
8210            if (r.crashing) {
8211                report.type = ApplicationErrorReport.TYPE_CRASH;
8212                report.crashInfo = new ApplicationErrorReport.CrashInfo();
8213
8214                ByteArrayInputStream byteStream = new ByteArrayInputStream(
8215                        r.crashingReport.crashData);
8216                DataInputStream dataStream = new DataInputStream(byteStream);
8217                CrashData crashData = new CrashData(dataStream);
8218                ThrowableData throwData = crashData.getThrowableData();
8219
8220                report.time = crashData.getTime();
8221                report.crashInfo.stackTrace = throwData.toString();
8222
8223                // extract the source of the exception, useful for report
8224                // clustering
8225                while (throwData.getCause() != null) {
8226                    throwData = throwData.getCause();
8227                }
8228                StackTraceElementData trace = throwData.getStackTrace()[0];
8229                report.crashInfo.exceptionClassName = throwData.getType();
8230                report.crashInfo.throwFileName = trace.getFileName();
8231                report.crashInfo.throwClassName = trace.getClassName();
8232                report.crashInfo.throwMethodName = trace.getMethodName();
8233            } else if (r.notResponding) {
8234                report.type = ApplicationErrorReport.TYPE_ANR;
8235                report.anrInfo = new ApplicationErrorReport.AnrInfo();
8236
8237                report.anrInfo.activity = r.notRespondingReport.tag;
8238                report.anrInfo.cause = r.notRespondingReport.shortMsg;
8239                report.anrInfo.info = r.notRespondingReport.longMsg;
8240            }
8241
8242            return report;
8243        } catch (IOException e) {
8244            // we don't send it
8245        }
8246
8247        return null;
8248    }
8249
8250    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
8251        // assume our apps are happy - lazy create the list
8252        List<ActivityManager.ProcessErrorStateInfo> errList = null;
8253
8254        synchronized (this) {
8255
8256            // iterate across all processes
8257            final int N = mLRUProcesses.size();
8258            for (int i = 0; i < N; i++) {
8259                ProcessRecord app = mLRUProcesses.get(i);
8260                if ((app.thread != null) && (app.crashing || app.notResponding)) {
8261                    // This one's in trouble, so we'll generate a report for it
8262                    // crashes are higher priority (in case there's a crash *and* an anr)
8263                    ActivityManager.ProcessErrorStateInfo report = null;
8264                    if (app.crashing) {
8265                        report = app.crashingReport;
8266                    } else if (app.notResponding) {
8267                        report = app.notRespondingReport;
8268                    }
8269
8270                    if (report != null) {
8271                        if (errList == null) {
8272                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
8273                        }
8274                        errList.add(report);
8275                    } else {
8276                        Log.w(TAG, "Missing app error report, app = " + app.processName +
8277                                " crashing = " + app.crashing +
8278                                " notResponding = " + app.notResponding);
8279                    }
8280                }
8281            }
8282        }
8283
8284        return errList;
8285    }
8286
8287    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
8288        // Lazy instantiation of list
8289        List<ActivityManager.RunningAppProcessInfo> runList = null;
8290        synchronized (this) {
8291            // Iterate across all processes
8292            final int N = mLRUProcesses.size();
8293            for (int i = 0; i < N; i++) {
8294                ProcessRecord app = mLRUProcesses.get(i);
8295                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
8296                    // Generate process state info for running application
8297                    ActivityManager.RunningAppProcessInfo currApp =
8298                        new ActivityManager.RunningAppProcessInfo(app.processName,
8299                                app.pid, app.getPackageList());
8300                    int adj = app.curAdj;
8301                    if (adj >= CONTENT_PROVIDER_ADJ) {
8302                        currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_EMPTY;
8303                    } else if (adj >= HIDDEN_APP_MIN_ADJ) {
8304                        currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
8305                        currApp.lru = adj - HIDDEN_APP_MIN_ADJ + 1;
8306                    } else if (adj >= HOME_APP_ADJ) {
8307                        currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
8308                        currApp.lru = 0;
8309                    } else if (adj >= SECONDARY_SERVER_ADJ) {
8310                        currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
8311                    } else if (adj >= VISIBLE_APP_ADJ) {
8312                        currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
8313                    } else {
8314                        currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
8315                    }
8316                    //Log.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
8317                    //        + " lru=" + currApp.lru);
8318                    if (runList == null) {
8319                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
8320                    }
8321                    runList.add(currApp);
8322                }
8323            }
8324        }
8325        return runList;
8326    }
8327
8328    @Override
8329    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
8330        synchronized (this) {
8331            if (checkCallingPermission(android.Manifest.permission.DUMP)
8332                    != PackageManager.PERMISSION_GRANTED) {
8333                pw.println("Permission Denial: can't dump ActivityManager from from pid="
8334                        + Binder.getCallingPid()
8335                        + ", uid=" + Binder.getCallingUid()
8336                        + " without permission "
8337                        + android.Manifest.permission.DUMP);
8338                return;
8339            }
8340            if (args.length != 0 && "service".equals(args[0])) {
8341                dumpService(fd, pw, args);
8342                return;
8343            }
8344            pw.println("Activities in Current Activity Manager State:");
8345            dumpHistoryList(pw, mHistory, "  ", "Hist", true);
8346            pw.println(" ");
8347            pw.println("  Running activities (most recent first):");
8348            dumpHistoryList(pw, mLRUActivities, "  ", "Run", false);
8349            if (mWaitingVisibleActivities.size() > 0) {
8350                pw.println(" ");
8351                pw.println("  Activities waiting for another to become visible:");
8352                dumpHistoryList(pw, mWaitingVisibleActivities, "  ", "Wait", false);
8353            }
8354            if (mStoppingActivities.size() > 0) {
8355                pw.println(" ");
8356                pw.println("  Activities waiting to stop:");
8357                dumpHistoryList(pw, mStoppingActivities, "  ", "Stop", false);
8358            }
8359            if (mFinishingActivities.size() > 0) {
8360                pw.println(" ");
8361                pw.println("  Activities waiting to finish:");
8362                dumpHistoryList(pw, mFinishingActivities, "  ", "Fin", false);
8363            }
8364
8365            pw.println(" ");
8366            pw.println("  mPausingActivity: " + mPausingActivity);
8367            pw.println("  mResumedActivity: " + mResumedActivity);
8368            pw.println("  mFocusedActivity: " + mFocusedActivity);
8369            pw.println("  mLastPausedActivity: " + mLastPausedActivity);
8370
8371            if (mRecentTasks.size() > 0) {
8372                pw.println(" ");
8373                pw.println("Recent tasks in Current Activity Manager State:");
8374
8375                final int N = mRecentTasks.size();
8376                for (int i=0; i<N; i++) {
8377                    TaskRecord tr = mRecentTasks.get(i);
8378                    pw.print("  * Recent #"); pw.print(i); pw.print(": ");
8379                            pw.println(tr);
8380                    mRecentTasks.get(i).dump(pw, "    ");
8381                }
8382            }
8383
8384            pw.println(" ");
8385            pw.println("  mCurTask: " + mCurTask);
8386
8387            pw.println(" ");
8388            pw.println("Processes in Current Activity Manager State:");
8389
8390            boolean needSep = false;
8391            int numPers = 0;
8392
8393            for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
8394                final int NA = procs.size();
8395                for (int ia=0; ia<NA; ia++) {
8396                    if (!needSep) {
8397                        pw.println("  All known processes:");
8398                        needSep = true;
8399                    }
8400                    ProcessRecord r = procs.valueAt(ia);
8401                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
8402                        pw.print(" UID "); pw.print(procs.keyAt(ia));
8403                        pw.print(" "); pw.println(r);
8404                    r.dump(pw, "    ");
8405                    if (r.persistent) {
8406                        numPers++;
8407                    }
8408                }
8409            }
8410
8411            if (mLRUProcesses.size() > 0) {
8412                if (needSep) pw.println(" ");
8413                needSep = true;
8414                pw.println("  Running processes (most recent first):");
8415                dumpProcessList(pw, mLRUProcesses, "    ",
8416                        "App ", "PERS", true);
8417                needSep = true;
8418            }
8419
8420            synchronized (mPidsSelfLocked) {
8421                if (mPidsSelfLocked.size() > 0) {
8422                    if (needSep) pw.println(" ");
8423                    needSep = true;
8424                    pw.println("  PID mappings:");
8425                    for (int i=0; i<mPidsSelfLocked.size(); i++) {
8426                        pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
8427                            pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
8428                    }
8429                }
8430            }
8431
8432            if (mForegroundProcesses.size() > 0) {
8433                if (needSep) pw.println(" ");
8434                needSep = true;
8435                pw.println("  Foreground Processes:");
8436                for (int i=0; i<mForegroundProcesses.size(); i++) {
8437                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
8438                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
8439                }
8440            }
8441
8442            if (mPersistentStartingProcesses.size() > 0) {
8443                if (needSep) pw.println(" ");
8444                needSep = true;
8445                pw.println("  Persisent processes that are starting:");
8446                dumpProcessList(pw, mPersistentStartingProcesses, "    ",
8447                        "Starting Norm", "Restarting PERS", false);
8448            }
8449
8450            if (mStartingProcesses.size() > 0) {
8451                if (needSep) pw.println(" ");
8452                needSep = true;
8453                pw.println("  Processes that are starting:");
8454                dumpProcessList(pw, mStartingProcesses, "    ",
8455                        "Starting Norm", "Starting PERS", false);
8456            }
8457
8458            if (mRemovedProcesses.size() > 0) {
8459                if (needSep) pw.println(" ");
8460                needSep = true;
8461                pw.println("  Processes that are being removed:");
8462                dumpProcessList(pw, mRemovedProcesses, "    ",
8463                        "Removed Norm", "Removed PERS", false);
8464            }
8465
8466            if (mProcessesOnHold.size() > 0) {
8467                if (needSep) pw.println(" ");
8468                needSep = true;
8469                pw.println("  Processes that are on old until the system is ready:");
8470                dumpProcessList(pw, mProcessesOnHold, "    ",
8471                        "OnHold Norm", "OnHold PERS", false);
8472            }
8473
8474            if (mProcessCrashTimes.getMap().size() > 0) {
8475                if (needSep) pw.println(" ");
8476                needSep = true;
8477                pw.println("  Time since processes crashed:");
8478                long now = SystemClock.uptimeMillis();
8479                for (Map.Entry<String, SparseArray<Long>> procs
8480                        : mProcessCrashTimes.getMap().entrySet()) {
8481                    SparseArray<Long> uids = procs.getValue();
8482                    final int N = uids.size();
8483                    for (int i=0; i<N; i++) {
8484                        pw.print("    Process "); pw.print(procs.getKey());
8485                                pw.print(" uid "); pw.print(uids.keyAt(i));
8486                                pw.print(": last crashed ");
8487                                pw.print((now-uids.valueAt(i)));
8488                                pw.println(" ms ago");
8489                    }
8490                }
8491            }
8492
8493            if (mBadProcesses.getMap().size() > 0) {
8494                if (needSep) pw.println(" ");
8495                needSep = true;
8496                pw.println("  Bad processes:");
8497                for (Map.Entry<String, SparseArray<Long>> procs
8498                        : mBadProcesses.getMap().entrySet()) {
8499                    SparseArray<Long> uids = procs.getValue();
8500                    final int N = uids.size();
8501                    for (int i=0; i<N; i++) {
8502                        pw.print("    Bad process "); pw.print(procs.getKey());
8503                                pw.print(" uid "); pw.print(uids.keyAt(i));
8504                                pw.print(": crashed at time ");
8505                                pw.println(uids.valueAt(i));
8506                    }
8507                }
8508            }
8509
8510            pw.println(" ");
8511            pw.println("  Total persistent processes: " + numPers);
8512            pw.println("  mHomeProcess: " + mHomeProcess);
8513            pw.println("  mConfiguration: " + mConfiguration);
8514            pw.println("  mStartRunning=" + mStartRunning
8515                    + " mSystemReady=" + mSystemReady
8516                    + " mBooting=" + mBooting
8517                    + " mBooted=" + mBooted
8518                    + " mFactoryTest=" + mFactoryTest);
8519            pw.println("  mSleeping=" + mSleeping + " mShuttingDown=" + mShuttingDown);
8520            pw.println("  mGoingToSleep=" + mGoingToSleep);
8521            pw.println("  mLaunchingActivity=" + mLaunchingActivity);
8522            pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
8523                    + " mDebugTransient=" + mDebugTransient
8524                    + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
8525            pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
8526                    + " mWatcher=" + mWatcher);
8527        }
8528    }
8529
8530    /**
8531     * There are three ways to call this:
8532     *  - no service specified: dump all the services
8533     *  - a flattened component name that matched an existing service was specified as the
8534     *    first arg: dump that one service
8535     *  - the first arg isn't the flattened component name of an existing service:
8536     *    dump all services whose component contains the first arg as a substring
8537     */
8538    protected void dumpService(FileDescriptor fd, PrintWriter pw, String[] args) {
8539        String[] newArgs;
8540        String componentNameString;
8541        ServiceRecord r;
8542        if (args.length == 1) {
8543            componentNameString = null;
8544            newArgs = EMPTY_STRING_ARRAY;
8545            r = null;
8546        } else {
8547            componentNameString = args[1];
8548            ComponentName componentName = ComponentName.unflattenFromString(componentNameString);
8549            r = componentName != null ? mServices.get(componentName) : null;
8550            newArgs = new String[args.length - 2];
8551            if (args.length > 2) System.arraycopy(args, 2, newArgs, 0, args.length - 2);
8552        }
8553
8554        if (r != null) {
8555            dumpService(fd, pw, r, newArgs);
8556        } else {
8557            for (ServiceRecord r1 : mServices.values()) {
8558                if (componentNameString == null
8559                        || r1.name.flattenToString().contains(componentNameString)) {
8560                    dumpService(fd, pw, r1, newArgs);
8561                }
8562            }
8563        }
8564    }
8565
8566    /**
8567     * Invokes IApplicationThread.dumpService() on the thread of the specified service if
8568     * there is a thread associated with the service.
8569     */
8570    private void dumpService(FileDescriptor fd, PrintWriter pw, ServiceRecord r, String[] args) {
8571        pw.println("  Service " + r.name.flattenToString());
8572        if (r.app != null && r.app.thread != null) {
8573            try {
8574                // flush anything that is already in the PrintWriter since the thread is going
8575                // to write to the file descriptor directly
8576                pw.flush();
8577                r.app.thread.dumpService(fd, r, args);
8578                pw.print("\n");
8579            } catch (RemoteException e) {
8580                pw.println("got a RemoteException while dumping the service");
8581            }
8582        }
8583    }
8584
8585    void dumpBroadcasts(PrintWriter pw) {
8586        synchronized (this) {
8587            if (checkCallingPermission(android.Manifest.permission.DUMP)
8588                    != PackageManager.PERMISSION_GRANTED) {
8589                pw.println("Permission Denial: can't dump ActivityManager from from pid="
8590                        + Binder.getCallingPid()
8591                        + ", uid=" + Binder.getCallingUid()
8592                        + " without permission "
8593                        + android.Manifest.permission.DUMP);
8594                return;
8595            }
8596            pw.println("Broadcasts in Current Activity Manager State:");
8597
8598            if (mRegisteredReceivers.size() > 0) {
8599                pw.println(" ");
8600                pw.println("  Registered Receivers:");
8601                Iterator it = mRegisteredReceivers.values().iterator();
8602                while (it.hasNext()) {
8603                    ReceiverList r = (ReceiverList)it.next();
8604                    pw.print("  * "); pw.println(r);
8605                    r.dump(pw, "    ");
8606                }
8607            }
8608
8609            pw.println(" ");
8610            pw.println("Receiver Resolver Table:");
8611            mReceiverResolver.dump(pw, "  ");
8612
8613            if (mParallelBroadcasts.size() > 0 || mOrderedBroadcasts.size() > 0
8614                    || mPendingBroadcast != null) {
8615                if (mParallelBroadcasts.size() > 0) {
8616                    pw.println(" ");
8617                    pw.println("  Active broadcasts:");
8618                }
8619                for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
8620                    pw.println("  Broadcast #" + i + ":");
8621                    mParallelBroadcasts.get(i).dump(pw, "    ");
8622                }
8623                if (mOrderedBroadcasts.size() > 0) {
8624                    pw.println(" ");
8625                    pw.println("  Active serialized broadcasts:");
8626                }
8627                for (int i=mOrderedBroadcasts.size()-1; i>=0; i--) {
8628                    pw.println("  Serialized Broadcast #" + i + ":");
8629                    mOrderedBroadcasts.get(i).dump(pw, "    ");
8630                }
8631                pw.println(" ");
8632                pw.println("  Pending broadcast:");
8633                if (mPendingBroadcast != null) {
8634                    mPendingBroadcast.dump(pw, "    ");
8635                } else {
8636                    pw.println("    (null)");
8637                }
8638            }
8639
8640            pw.println(" ");
8641            pw.println("  mBroadcastsScheduled=" + mBroadcastsScheduled);
8642            if (mStickyBroadcasts != null) {
8643                pw.println(" ");
8644                pw.println("  Sticky broadcasts:");
8645                StringBuilder sb = new StringBuilder(128);
8646                for (Map.Entry<String, ArrayList<Intent>> ent
8647                        : mStickyBroadcasts.entrySet()) {
8648                    pw.print("  * Sticky action "); pw.print(ent.getKey());
8649                            pw.println(":");
8650                    ArrayList<Intent> intents = ent.getValue();
8651                    final int N = intents.size();
8652                    for (int i=0; i<N; i++) {
8653                        sb.setLength(0);
8654                        sb.append("    Intent: ");
8655                        intents.get(i).toShortString(sb, true, false);
8656                        pw.println(sb.toString());
8657                        Bundle bundle = intents.get(i).getExtras();
8658                        if (bundle != null) {
8659                            pw.print("      ");
8660                            pw.println(bundle.toString());
8661                        }
8662                    }
8663                }
8664            }
8665
8666            pw.println(" ");
8667            pw.println("  mHandler:");
8668            mHandler.dump(new PrintWriterPrinter(pw), "    ");
8669        }
8670    }
8671
8672    void dumpServices(PrintWriter pw) {
8673        synchronized (this) {
8674            if (checkCallingPermission(android.Manifest.permission.DUMP)
8675                    != PackageManager.PERMISSION_GRANTED) {
8676                pw.println("Permission Denial: can't dump ActivityManager from from pid="
8677                        + Binder.getCallingPid()
8678                        + ", uid=" + Binder.getCallingUid()
8679                        + " without permission "
8680                        + android.Manifest.permission.DUMP);
8681                return;
8682            }
8683            pw.println("Services in Current Activity Manager State:");
8684
8685            boolean needSep = false;
8686
8687            if (mServices.size() > 0) {
8688                pw.println("  Active services:");
8689                Iterator<ServiceRecord> it = mServices.values().iterator();
8690                while (it.hasNext()) {
8691                    ServiceRecord r = it.next();
8692                    pw.print("  * "); pw.println(r);
8693                    r.dump(pw, "    ");
8694                }
8695                needSep = true;
8696            }
8697
8698            if (mPendingServices.size() > 0) {
8699                if (needSep) pw.println(" ");
8700                pw.println("  Pending services:");
8701                for (int i=0; i<mPendingServices.size(); i++) {
8702                    ServiceRecord r = mPendingServices.get(i);
8703                    pw.print("  * Pending "); pw.println(r);
8704                    r.dump(pw, "    ");
8705                }
8706                needSep = true;
8707            }
8708
8709            if (mRestartingServices.size() > 0) {
8710                if (needSep) pw.println(" ");
8711                pw.println("  Restarting services:");
8712                for (int i=0; i<mRestartingServices.size(); i++) {
8713                    ServiceRecord r = mRestartingServices.get(i);
8714                    pw.print("  * Restarting "); pw.println(r);
8715                    r.dump(pw, "    ");
8716                }
8717                needSep = true;
8718            }
8719
8720            if (mStoppingServices.size() > 0) {
8721                if (needSep) pw.println(" ");
8722                pw.println("  Stopping services:");
8723                for (int i=0; i<mStoppingServices.size(); i++) {
8724                    ServiceRecord r = mStoppingServices.get(i);
8725                    pw.print("  * Stopping "); pw.println(r);
8726                    r.dump(pw, "    ");
8727                }
8728                needSep = true;
8729            }
8730
8731            if (mServiceConnections.size() > 0) {
8732                if (needSep) pw.println(" ");
8733                pw.println("  Connection bindings to services:");
8734                Iterator<ConnectionRecord> it
8735                        = mServiceConnections.values().iterator();
8736                while (it.hasNext()) {
8737                    ConnectionRecord r = it.next();
8738                    pw.print("  * "); pw.println(r);
8739                    r.dump(pw, "    ");
8740                }
8741            }
8742        }
8743    }
8744
8745    void dumpProviders(PrintWriter pw) {
8746        synchronized (this) {
8747            if (checkCallingPermission(android.Manifest.permission.DUMP)
8748                    != PackageManager.PERMISSION_GRANTED) {
8749                pw.println("Permission Denial: can't dump ActivityManager from from pid="
8750                        + Binder.getCallingPid()
8751                        + ", uid=" + Binder.getCallingUid()
8752                        + " without permission "
8753                        + android.Manifest.permission.DUMP);
8754                return;
8755            }
8756
8757            pw.println("Content Providers in Current Activity Manager State:");
8758
8759            boolean needSep = false;
8760
8761            if (mProvidersByClass.size() > 0) {
8762                if (needSep) pw.println(" ");
8763                pw.println("  Published content providers (by class):");
8764                Iterator it = mProvidersByClass.entrySet().iterator();
8765                while (it.hasNext()) {
8766                    Map.Entry e = (Map.Entry)it.next();
8767                    ContentProviderRecord r = (ContentProviderRecord)e.getValue();
8768                    pw.print("  * "); pw.println(r);
8769                    r.dump(pw, "    ");
8770                }
8771                needSep = true;
8772            }
8773
8774            if (mProvidersByName.size() > 0) {
8775                pw.println(" ");
8776                pw.println("  Authority to provider mappings:");
8777                Iterator it = mProvidersByName.entrySet().iterator();
8778                while (it.hasNext()) {
8779                    Map.Entry e = (Map.Entry)it.next();
8780                    ContentProviderRecord r = (ContentProviderRecord)e.getValue();
8781                    pw.print("  "); pw.print(e.getKey()); pw.print(": ");
8782                            pw.println(r);
8783                }
8784                needSep = true;
8785            }
8786
8787            if (mLaunchingProviders.size() > 0) {
8788                if (needSep) pw.println(" ");
8789                pw.println("  Launching content providers:");
8790                for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
8791                    pw.print("  Launching #"); pw.print(i); pw.print(": ");
8792                            pw.println(mLaunchingProviders.get(i));
8793                }
8794                needSep = true;
8795            }
8796
8797            if (mGrantedUriPermissions.size() > 0) {
8798                pw.println();
8799                pw.println("Granted Uri Permissions:");
8800                for (int i=0; i<mGrantedUriPermissions.size(); i++) {
8801                    int uid = mGrantedUriPermissions.keyAt(i);
8802                    HashMap<Uri, UriPermission> perms
8803                            = mGrantedUriPermissions.valueAt(i);
8804                    pw.print("  * UID "); pw.print(uid);
8805                            pw.println(" holds:");
8806                    for (UriPermission perm : perms.values()) {
8807                        pw.print("    "); pw.println(perm);
8808                        perm.dump(pw, "      ");
8809                    }
8810                }
8811            }
8812        }
8813    }
8814
8815    void dumpSenders(PrintWriter pw) {
8816        synchronized (this) {
8817            if (checkCallingPermission(android.Manifest.permission.DUMP)
8818                    != PackageManager.PERMISSION_GRANTED) {
8819                pw.println("Permission Denial: can't dump ActivityManager from from pid="
8820                        + Binder.getCallingPid()
8821                        + ", uid=" + Binder.getCallingUid()
8822                        + " without permission "
8823                        + android.Manifest.permission.DUMP);
8824                return;
8825            }
8826
8827            pw.println("Pending Intents in Current Activity Manager State:");
8828
8829            if (this.mIntentSenderRecords.size() > 0) {
8830                Iterator<WeakReference<PendingIntentRecord>> it
8831                        = mIntentSenderRecords.values().iterator();
8832                while (it.hasNext()) {
8833                    WeakReference<PendingIntentRecord> ref = it.next();
8834                    PendingIntentRecord rec = ref != null ? ref.get(): null;
8835                    if (rec != null) {
8836                        pw.print("  * "); pw.println(rec);
8837                        rec.dump(pw, "    ");
8838                    } else {
8839                        pw.print("  * "); pw.print(ref);
8840                    }
8841                }
8842            }
8843        }
8844    }
8845
8846    private static final void dumpHistoryList(PrintWriter pw, List list,
8847            String prefix, String label, boolean complete) {
8848        TaskRecord lastTask = null;
8849        for (int i=list.size()-1; i>=0; i--) {
8850            HistoryRecord r = (HistoryRecord)list.get(i);
8851            final boolean full = complete || !r.inHistory;
8852            if (lastTask != r.task) {
8853                lastTask = r.task;
8854                pw.print(prefix);
8855                pw.print(full ? "* " : "  ");
8856                pw.println(lastTask);
8857                if (full) {
8858                    lastTask.dump(pw, prefix + "  ");
8859                }
8860            }
8861            pw.print(prefix); pw.print(full ? "  * " : "    "); pw.print(label);
8862            pw.print(" #"); pw.print(i); pw.print(": ");
8863            pw.println(r);
8864            if (full) {
8865                r.dump(pw, prefix + "      ");
8866            }
8867        }
8868    }
8869
8870    private static final int dumpProcessList(PrintWriter pw, List list,
8871            String prefix, String normalLabel, String persistentLabel,
8872            boolean inclOomAdj) {
8873        int numPers = 0;
8874        for (int i=list.size()-1; i>=0; i--) {
8875            ProcessRecord r = (ProcessRecord)list.get(i);
8876            if (false) {
8877                pw.println(prefix + (r.persistent ? persistentLabel : normalLabel)
8878                      + " #" + i + ":");
8879                r.dump(pw, prefix + "  ");
8880            } else if (inclOomAdj) {
8881                pw.println(String.format("%s%s #%2d: adj=%3d/%d %s",
8882                        prefix, (r.persistent ? persistentLabel : normalLabel),
8883                        i, r.setAdj, r.setSchedGroup, r.toString()));
8884            } else {
8885                pw.println(String.format("%s%s #%2d: %s",
8886                        prefix, (r.persistent ? persistentLabel : normalLabel),
8887                        i, r.toString()));
8888            }
8889            if (r.persistent) {
8890                numPers++;
8891            }
8892        }
8893        return numPers;
8894    }
8895
8896    private static final void dumpApplicationMemoryUsage(FileDescriptor fd,
8897            PrintWriter pw, List list, String prefix, String[] args) {
8898        final boolean isCheckinRequest = scanArgs(args, "--checkin");
8899        long uptime = SystemClock.uptimeMillis();
8900        long realtime = SystemClock.elapsedRealtime();
8901
8902        if (isCheckinRequest) {
8903            // short checkin version
8904            pw.println(uptime + "," + realtime);
8905            pw.flush();
8906        } else {
8907            pw.println("Applications Memory Usage (kB):");
8908            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
8909        }
8910        for (int i = list.size() - 1 ; i >= 0 ; i--) {
8911            ProcessRecord r = (ProcessRecord)list.get(i);
8912            if (r.thread != null) {
8913                if (!isCheckinRequest) {
8914                    pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
8915                    pw.flush();
8916                }
8917                try {
8918                    r.thread.asBinder().dump(fd, args);
8919                } catch (RemoteException e) {
8920                    if (!isCheckinRequest) {
8921                        pw.println("Got RemoteException!");
8922                        pw.flush();
8923                    }
8924                }
8925            }
8926        }
8927    }
8928
8929    /**
8930     * Searches array of arguments for the specified string
8931     * @param args array of argument strings
8932     * @param value value to search for
8933     * @return true if the value is contained in the array
8934     */
8935    private static boolean scanArgs(String[] args, String value) {
8936        if (args != null) {
8937            for (String arg : args) {
8938                if (value.equals(arg)) {
8939                    return true;
8940                }
8941            }
8942        }
8943        return false;
8944    }
8945
8946    private final int indexOfTokenLocked(IBinder token, boolean required) {
8947        int count = mHistory.size();
8948
8949        // convert the token to an entry in the history.
8950        HistoryRecord r = null;
8951        int index = -1;
8952        for (int i=count-1; i>=0; i--) {
8953            Object o = mHistory.get(i);
8954            if (o == token) {
8955                r = (HistoryRecord)o;
8956                index = i;
8957                break;
8958            }
8959        }
8960        if (index < 0 && required) {
8961            RuntimeInit.crash(TAG, new InvalidTokenException(token));
8962        }
8963
8964        return index;
8965    }
8966
8967    static class InvalidTokenException extends Exception {
8968        InvalidTokenException(IBinder token) {
8969            super("Bad activity token: " + token);
8970        }
8971    }
8972
8973    private final void killServicesLocked(ProcessRecord app,
8974            boolean allowRestart) {
8975        // Report disconnected services.
8976        if (false) {
8977            // XXX we are letting the client link to the service for
8978            // death notifications.
8979            if (app.services.size() > 0) {
8980                Iterator it = app.services.iterator();
8981                while (it.hasNext()) {
8982                    ServiceRecord r = (ServiceRecord)it.next();
8983                    if (r.connections.size() > 0) {
8984                        Iterator<ConnectionRecord> jt
8985                                = r.connections.values().iterator();
8986                        while (jt.hasNext()) {
8987                            ConnectionRecord c = jt.next();
8988                            if (c.binding.client != app) {
8989                                try {
8990                                    //c.conn.connected(r.className, null);
8991                                } catch (Exception e) {
8992                                    // todo: this should be asynchronous!
8993                                    Log.w(TAG, "Exception thrown disconnected servce "
8994                                          + r.shortName
8995                                          + " from app " + app.processName, e);
8996                                }
8997                            }
8998                        }
8999                    }
9000                }
9001            }
9002        }
9003
9004        // Clean up any connections this application has to other services.
9005        if (app.connections.size() > 0) {
9006            Iterator<ConnectionRecord> it = app.connections.iterator();
9007            while (it.hasNext()) {
9008                ConnectionRecord r = it.next();
9009                removeConnectionLocked(r, app, null);
9010            }
9011        }
9012        app.connections.clear();
9013
9014        if (app.services.size() != 0) {
9015            // Any services running in the application need to be placed
9016            // back in the pending list.
9017            Iterator it = app.services.iterator();
9018            while (it.hasNext()) {
9019                ServiceRecord sr = (ServiceRecord)it.next();
9020                synchronized (sr.stats.getBatteryStats()) {
9021                    sr.stats.stopLaunchedLocked();
9022                }
9023                sr.app = null;
9024                sr.executeNesting = 0;
9025                mStoppingServices.remove(sr);
9026                if (sr.bindings.size() > 0) {
9027                    Iterator<IntentBindRecord> bindings
9028                            = sr.bindings.values().iterator();
9029                    while (bindings.hasNext()) {
9030                        IntentBindRecord b = bindings.next();
9031                        if (DEBUG_SERVICE) Log.v(TAG, "Killing binding " + b
9032                                + ": shouldUnbind=" + b.hasBound);
9033                        b.binder = null;
9034                        b.requested = b.received = b.hasBound = false;
9035                    }
9036                }
9037
9038                if (sr.crashCount >= 2) {
9039                    Log.w(TAG, "Service crashed " + sr.crashCount
9040                            + " times, stopping: " + sr);
9041                    EventLog.writeEvent(LOG_AM_SERVICE_CRASHED_TOO_MUCH,
9042                            sr.crashCount, sr.shortName, app.pid);
9043                    bringDownServiceLocked(sr, true);
9044                } else if (!allowRestart) {
9045                    bringDownServiceLocked(sr, true);
9046                } else {
9047                    scheduleServiceRestartLocked(sr);
9048                }
9049            }
9050
9051            if (!allowRestart) {
9052                app.services.clear();
9053            }
9054        }
9055
9056        app.executingServices.clear();
9057    }
9058
9059    private final void removeDyingProviderLocked(ProcessRecord proc,
9060            ContentProviderRecord cpr) {
9061        synchronized (cpr) {
9062            cpr.launchingApp = null;
9063            cpr.notifyAll();
9064        }
9065
9066        mProvidersByClass.remove(cpr.info.name);
9067        String names[] = cpr.info.authority.split(";");
9068        for (int j = 0; j < names.length; j++) {
9069            mProvidersByName.remove(names[j]);
9070        }
9071
9072        Iterator<ProcessRecord> cit = cpr.clients.iterator();
9073        while (cit.hasNext()) {
9074            ProcessRecord capp = cit.next();
9075            if (!capp.persistent && capp.thread != null
9076                    && capp.pid != 0
9077                    && capp.pid != MY_PID) {
9078                Log.i(TAG, "Killing app " + capp.processName
9079                        + " (pid " + capp.pid
9080                        + ") because provider " + cpr.info.name
9081                        + " is in dying process " + proc.processName);
9082                Process.killProcess(capp.pid);
9083            }
9084        }
9085
9086        mLaunchingProviders.remove(cpr);
9087    }
9088
9089    /**
9090     * Main code for cleaning up a process when it has gone away.  This is
9091     * called both as a result of the process dying, or directly when stopping
9092     * a process when running in single process mode.
9093     */
9094    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
9095            boolean restarting, int index) {
9096        if (index >= 0) {
9097            mLRUProcesses.remove(index);
9098        }
9099
9100        // Dismiss any open dialogs.
9101        if (app.crashDialog != null) {
9102            app.crashDialog.dismiss();
9103            app.crashDialog = null;
9104        }
9105        if (app.anrDialog != null) {
9106            app.anrDialog.dismiss();
9107            app.anrDialog = null;
9108        }
9109        if (app.waitDialog != null) {
9110            app.waitDialog.dismiss();
9111            app.waitDialog = null;
9112        }
9113
9114        app.crashing = false;
9115        app.notResponding = false;
9116
9117        app.resetPackageList();
9118        app.thread = null;
9119        app.forcingToForeground = null;
9120        app.foregroundServices = false;
9121
9122        killServicesLocked(app, true);
9123
9124        boolean restart = false;
9125
9126        int NL = mLaunchingProviders.size();
9127
9128        // Remove published content providers.
9129        if (!app.pubProviders.isEmpty()) {
9130            Iterator it = app.pubProviders.values().iterator();
9131            while (it.hasNext()) {
9132                ContentProviderRecord cpr = (ContentProviderRecord)it.next();
9133                cpr.provider = null;
9134                cpr.app = null;
9135
9136                // See if someone is waiting for this provider...  in which
9137                // case we don't remove it, but just let it restart.
9138                int i = 0;
9139                if (!app.bad) {
9140                    for (; i<NL; i++) {
9141                        if (mLaunchingProviders.get(i) == cpr) {
9142                            restart = true;
9143                            break;
9144                        }
9145                    }
9146                } else {
9147                    i = NL;
9148                }
9149
9150                if (i >= NL) {
9151                    removeDyingProviderLocked(app, cpr);
9152                    NL = mLaunchingProviders.size();
9153                }
9154            }
9155            app.pubProviders.clear();
9156        }
9157
9158        // Look through the content providers we are waiting to have launched,
9159        // and if any run in this process then either schedule a restart of
9160        // the process or kill the client waiting for it if this process has
9161        // gone bad.
9162        for (int i=0; i<NL; i++) {
9163            ContentProviderRecord cpr = (ContentProviderRecord)
9164                    mLaunchingProviders.get(i);
9165            if (cpr.launchingApp == app) {
9166                if (!app.bad) {
9167                    restart = true;
9168                } else {
9169                    removeDyingProviderLocked(app, cpr);
9170                    NL = mLaunchingProviders.size();
9171                }
9172            }
9173        }
9174
9175        // Unregister from connected content providers.
9176        if (!app.conProviders.isEmpty()) {
9177            Iterator it = app.conProviders.iterator();
9178            while (it.hasNext()) {
9179                ContentProviderRecord cpr = (ContentProviderRecord)it.next();
9180                cpr.clients.remove(app);
9181            }
9182            app.conProviders.clear();
9183        }
9184
9185        skipCurrentReceiverLocked(app);
9186
9187        // Unregister any receivers.
9188        if (app.receivers.size() > 0) {
9189            Iterator<ReceiverList> it = app.receivers.iterator();
9190            while (it.hasNext()) {
9191                removeReceiverLocked(it.next());
9192            }
9193            app.receivers.clear();
9194        }
9195
9196        // If the app is undergoing backup, tell the backup manager about it
9197        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
9198            if (DEBUG_BACKUP) Log.d(TAG, "App " + mBackupTarget.appInfo + " died during backup");
9199            try {
9200                IBackupManager bm = IBackupManager.Stub.asInterface(
9201                        ServiceManager.getService(Context.BACKUP_SERVICE));
9202                bm.agentDisconnected(app.info.packageName);
9203            } catch (RemoteException e) {
9204                // can't happen; backup manager is local
9205            }
9206        }
9207
9208        // If the caller is restarting this app, then leave it in its
9209        // current lists and let the caller take care of it.
9210        if (restarting) {
9211            return;
9212        }
9213
9214        if (!app.persistent) {
9215            if (DEBUG_PROCESSES) Log.v(TAG,
9216                    "Removing non-persistent process during cleanup: " + app);
9217            mProcessNames.remove(app.processName, app.info.uid);
9218        } else if (!app.removed) {
9219            // This app is persistent, so we need to keep its record around.
9220            // If it is not already on the pending app list, add it there
9221            // and start a new process for it.
9222            app.thread = null;
9223            app.forcingToForeground = null;
9224            app.foregroundServices = false;
9225            if (mPersistentStartingProcesses.indexOf(app) < 0) {
9226                mPersistentStartingProcesses.add(app);
9227                restart = true;
9228            }
9229        }
9230        mProcessesOnHold.remove(app);
9231
9232        if (app == mHomeProcess) {
9233            mHomeProcess = null;
9234        }
9235
9236        if (restart) {
9237            // We have components that still need to be running in the
9238            // process, so re-launch it.
9239            mProcessNames.put(app.processName, app.info.uid, app);
9240            startProcessLocked(app, "restart", app.processName);
9241        } else if (app.pid > 0 && app.pid != MY_PID) {
9242            // Goodbye!
9243            synchronized (mPidsSelfLocked) {
9244                mPidsSelfLocked.remove(app.pid);
9245                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
9246            }
9247            app.setPid(0);
9248        }
9249    }
9250
9251    // =========================================================
9252    // SERVICES
9253    // =========================================================
9254
9255    ActivityManager.RunningServiceInfo makeRunningServiceInfoLocked(ServiceRecord r) {
9256        ActivityManager.RunningServiceInfo info =
9257            new ActivityManager.RunningServiceInfo();
9258        info.service = r.name;
9259        if (r.app != null) {
9260            info.pid = r.app.pid;
9261        }
9262        info.process = r.processName;
9263        info.foreground = r.isForeground;
9264        info.activeSince = r.createTime;
9265        info.started = r.startRequested;
9266        info.clientCount = r.connections.size();
9267        info.crashCount = r.crashCount;
9268        info.lastActivityTime = r.lastActivity;
9269        return info;
9270    }
9271
9272    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
9273            int flags) {
9274        synchronized (this) {
9275            ArrayList<ActivityManager.RunningServiceInfo> res
9276                    = new ArrayList<ActivityManager.RunningServiceInfo>();
9277
9278            if (mServices.size() > 0) {
9279                Iterator<ServiceRecord> it = mServices.values().iterator();
9280                while (it.hasNext() && res.size() < maxNum) {
9281                    res.add(makeRunningServiceInfoLocked(it.next()));
9282                }
9283            }
9284
9285            for (int i=0; i<mRestartingServices.size() && res.size() < maxNum; i++) {
9286                ServiceRecord r = mRestartingServices.get(i);
9287                ActivityManager.RunningServiceInfo info =
9288                        makeRunningServiceInfoLocked(r);
9289                info.restarting = r.nextRestartTime;
9290                res.add(info);
9291            }
9292
9293            return res;
9294        }
9295    }
9296
9297    private final ServiceRecord findServiceLocked(ComponentName name,
9298            IBinder token) {
9299        ServiceRecord r = mServices.get(name);
9300        return r == token ? r : null;
9301    }
9302
9303    private final class ServiceLookupResult {
9304        final ServiceRecord record;
9305        final String permission;
9306
9307        ServiceLookupResult(ServiceRecord _record, String _permission) {
9308            record = _record;
9309            permission = _permission;
9310        }
9311    };
9312
9313    private ServiceLookupResult findServiceLocked(Intent service,
9314            String resolvedType) {
9315        ServiceRecord r = null;
9316        if (service.getComponent() != null) {
9317            r = mServices.get(service.getComponent());
9318        }
9319        if (r == null) {
9320            Intent.FilterComparison filter = new Intent.FilterComparison(service);
9321            r = mServicesByIntent.get(filter);
9322        }
9323
9324        if (r == null) {
9325            try {
9326                ResolveInfo rInfo =
9327                    ActivityThread.getPackageManager().resolveService(
9328                            service, resolvedType, 0);
9329                ServiceInfo sInfo =
9330                    rInfo != null ? rInfo.serviceInfo : null;
9331                if (sInfo == null) {
9332                    return null;
9333                }
9334
9335                ComponentName name = new ComponentName(
9336                        sInfo.applicationInfo.packageName, sInfo.name);
9337                r = mServices.get(name);
9338            } catch (RemoteException ex) {
9339                // pm is in same process, this will never happen.
9340            }
9341        }
9342        if (r != null) {
9343            int callingPid = Binder.getCallingPid();
9344            int callingUid = Binder.getCallingUid();
9345            if (checkComponentPermission(r.permission,
9346                    callingPid, callingUid, r.exported ? -1 : r.appInfo.uid)
9347                    != PackageManager.PERMISSION_GRANTED) {
9348                Log.w(TAG, "Permission Denial: Accessing service " + r.name
9349                        + " from pid=" + callingPid
9350                        + ", uid=" + callingUid
9351                        + " requires " + r.permission);
9352                return new ServiceLookupResult(null, r.permission);
9353            }
9354            return new ServiceLookupResult(r, null);
9355        }
9356        return null;
9357    }
9358
9359    private class ServiceRestarter implements Runnable {
9360        private ServiceRecord mService;
9361
9362        void setService(ServiceRecord service) {
9363            mService = service;
9364        }
9365
9366        public void run() {
9367            synchronized(ActivityManagerService.this) {
9368                performServiceRestartLocked(mService);
9369            }
9370        }
9371    }
9372
9373    private ServiceLookupResult retrieveServiceLocked(Intent service,
9374            String resolvedType, int callingPid, int callingUid) {
9375        ServiceRecord r = null;
9376        if (service.getComponent() != null) {
9377            r = mServices.get(service.getComponent());
9378        }
9379        Intent.FilterComparison filter = new Intent.FilterComparison(service);
9380        r = mServicesByIntent.get(filter);
9381        if (r == null) {
9382            try {
9383                ResolveInfo rInfo =
9384                    ActivityThread.getPackageManager().resolveService(
9385                            service, resolvedType, STOCK_PM_FLAGS);
9386                ServiceInfo sInfo =
9387                    rInfo != null ? rInfo.serviceInfo : null;
9388                if (sInfo == null) {
9389                    Log.w(TAG, "Unable to start service " + service +
9390                          ": not found");
9391                    return null;
9392                }
9393
9394                ComponentName name = new ComponentName(
9395                        sInfo.applicationInfo.packageName, sInfo.name);
9396                r = mServices.get(name);
9397                if (r == null) {
9398                    filter = new Intent.FilterComparison(service.cloneFilter());
9399                    ServiceRestarter res = new ServiceRestarter();
9400                    BatteryStatsImpl.Uid.Pkg.Serv ss = null;
9401                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9402                    synchronized (stats) {
9403                        ss = stats.getServiceStatsLocked(
9404                                sInfo.applicationInfo.uid, sInfo.packageName,
9405                                sInfo.name);
9406                    }
9407                    r = new ServiceRecord(ss, name, filter, sInfo, res);
9408                    res.setService(r);
9409                    mServices.put(name, r);
9410                    mServicesByIntent.put(filter, r);
9411
9412                    // Make sure this component isn't in the pending list.
9413                    int N = mPendingServices.size();
9414                    for (int i=0; i<N; i++) {
9415                        ServiceRecord pr = mPendingServices.get(i);
9416                        if (pr.name.equals(name)) {
9417                            mPendingServices.remove(i);
9418                            i--;
9419                            N--;
9420                        }
9421                    }
9422                }
9423            } catch (RemoteException ex) {
9424                // pm is in same process, this will never happen.
9425            }
9426        }
9427        if (r != null) {
9428            if (checkComponentPermission(r.permission,
9429                    callingPid, callingUid, r.exported ? -1 : r.appInfo.uid)
9430                    != PackageManager.PERMISSION_GRANTED) {
9431                Log.w(TAG, "Permission Denial: Accessing service " + r.name
9432                        + " from pid=" + Binder.getCallingPid()
9433                        + ", uid=" + Binder.getCallingUid()
9434                        + " requires " + r.permission);
9435                return new ServiceLookupResult(null, r.permission);
9436            }
9437            return new ServiceLookupResult(r, null);
9438        }
9439        return null;
9440    }
9441
9442    private final void bumpServiceExecutingLocked(ServiceRecord r) {
9443        long now = SystemClock.uptimeMillis();
9444        if (r.executeNesting == 0 && r.app != null) {
9445            if (r.app.executingServices.size() == 0) {
9446                Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
9447                msg.obj = r.app;
9448                mHandler.sendMessageAtTime(msg, now+SERVICE_TIMEOUT);
9449            }
9450            r.app.executingServices.add(r);
9451        }
9452        r.executeNesting++;
9453        r.executingStart = now;
9454    }
9455
9456    private final void sendServiceArgsLocked(ServiceRecord r,
9457            boolean oomAdjusted) {
9458        final int N = r.startArgs.size();
9459        if (N == 0) {
9460            return;
9461        }
9462
9463        final int BASEID = r.lastStartId - N + 1;
9464        int i = 0;
9465        while (i < N) {
9466            try {
9467                Intent args = r.startArgs.get(i);
9468                if (DEBUG_SERVICE) Log.v(TAG, "Sending arguments to service: "
9469                        + r.name + " " + r.intent + " args=" + args);
9470                bumpServiceExecutingLocked(r);
9471                if (!oomAdjusted) {
9472                    oomAdjusted = true;
9473                    updateOomAdjLocked(r.app);
9474                }
9475                r.app.thread.scheduleServiceArgs(r, BASEID+i, args);
9476                i++;
9477            } catch (Exception e) {
9478                break;
9479            }
9480        }
9481        if (i == N) {
9482            r.startArgs.clear();
9483        } else {
9484            while (i > 0) {
9485                r.startArgs.remove(0);
9486                i--;
9487            }
9488        }
9489    }
9490
9491    private final boolean requestServiceBindingLocked(ServiceRecord r,
9492            IntentBindRecord i, boolean rebind) {
9493        if (r.app == null || r.app.thread == null) {
9494            // If service is not currently running, can't yet bind.
9495            return false;
9496        }
9497        if ((!i.requested || rebind) && i.apps.size() > 0) {
9498            try {
9499                bumpServiceExecutingLocked(r);
9500                if (DEBUG_SERVICE) Log.v(TAG, "Connecting binding " + i
9501                        + ": shouldUnbind=" + i.hasBound);
9502                r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind);
9503                if (!rebind) {
9504                    i.requested = true;
9505                }
9506                i.hasBound = true;
9507                i.doRebind = false;
9508            } catch (RemoteException e) {
9509                return false;
9510            }
9511        }
9512        return true;
9513    }
9514
9515    private final void requestServiceBindingsLocked(ServiceRecord r) {
9516        Iterator<IntentBindRecord> bindings = r.bindings.values().iterator();
9517        while (bindings.hasNext()) {
9518            IntentBindRecord i = bindings.next();
9519            if (!requestServiceBindingLocked(r, i, false)) {
9520                break;
9521            }
9522        }
9523    }
9524
9525    private final void realStartServiceLocked(ServiceRecord r,
9526            ProcessRecord app) throws RemoteException {
9527        if (app.thread == null) {
9528            throw new RemoteException();
9529        }
9530
9531        r.app = app;
9532        r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
9533
9534        app.services.add(r);
9535        bumpServiceExecutingLocked(r);
9536        updateLRUListLocked(app, true);
9537
9538        boolean created = false;
9539        try {
9540            if (DEBUG_SERVICE) Log.v(TAG, "Scheduling start service: "
9541                    + r.name + " " + r.intent);
9542            EventLog.writeEvent(LOG_AM_CREATE_SERVICE,
9543                    System.identityHashCode(r), r.shortName,
9544                    r.intent.getIntent().toString(), r.app.pid);
9545            synchronized (r.stats.getBatteryStats()) {
9546                r.stats.startLaunchedLocked();
9547            }
9548            app.thread.scheduleCreateService(r, r.serviceInfo);
9549            created = true;
9550        } finally {
9551            if (!created) {
9552                app.services.remove(r);
9553                scheduleServiceRestartLocked(r);
9554            }
9555        }
9556
9557        requestServiceBindingsLocked(r);
9558        sendServiceArgsLocked(r, true);
9559    }
9560
9561    private final void scheduleServiceRestartLocked(ServiceRecord r) {
9562        r.totalRestartCount++;
9563        if (r.restartDelay == 0) {
9564            r.restartCount++;
9565            r.restartDelay = SERVICE_RESTART_DURATION;
9566        } else {
9567            // If it has been a "reasonably long time" since the service
9568            // was started, then reset our restart duration back to
9569            // the beginning, so we don't infinitely increase the duration
9570            // on a service that just occasionally gets killed (which is
9571            // a normal case, due to process being killed to reclaim memory).
9572            long now = SystemClock.uptimeMillis();
9573            if (now > (r.restartTime+(SERVICE_RESTART_DURATION*2*2*2))) {
9574                r.restartCount = 1;
9575                r.restartDelay = SERVICE_RESTART_DURATION;
9576            } else {
9577                r.restartDelay *= 2;
9578            }
9579        }
9580        if (!mRestartingServices.contains(r)) {
9581            mRestartingServices.add(r);
9582        }
9583        mHandler.removeCallbacks(r.restarter);
9584        mHandler.postDelayed(r.restarter, r.restartDelay);
9585        r.nextRestartTime = SystemClock.uptimeMillis() + r.restartDelay;
9586        Log.w(TAG, "Scheduling restart of crashed service "
9587                + r.shortName + " in " + r.restartDelay + "ms");
9588        EventLog.writeEvent(LOG_AM_SCHEDULE_SERVICE_RESTART,
9589                r.shortName, r.restartDelay);
9590
9591        Message msg = Message.obtain();
9592        msg.what = SERVICE_ERROR_MSG;
9593        msg.obj = r;
9594        mHandler.sendMessage(msg);
9595    }
9596
9597    final void performServiceRestartLocked(ServiceRecord r) {
9598        if (!mRestartingServices.contains(r)) {
9599            return;
9600        }
9601        bringUpServiceLocked(r, r.intent.getIntent().getFlags(), true);
9602    }
9603
9604    private final boolean unscheduleServiceRestartLocked(ServiceRecord r) {
9605        if (r.restartDelay == 0) {
9606            return false;
9607        }
9608        r.resetRestartCounter();
9609        mRestartingServices.remove(r);
9610        mHandler.removeCallbacks(r.restarter);
9611        return true;
9612    }
9613
9614    private final boolean bringUpServiceLocked(ServiceRecord r,
9615            int intentFlags, boolean whileRestarting) {
9616        //Log.i(TAG, "Bring up service:");
9617        //r.dump("  ");
9618
9619        if (r.app != null) {
9620            sendServiceArgsLocked(r, false);
9621            return true;
9622        }
9623
9624        if (!whileRestarting && r.restartDelay > 0) {
9625            // If waiting for a restart, then do nothing.
9626            return true;
9627        }
9628
9629        if (DEBUG_SERVICE) Log.v(TAG, "Bringing up service " + r.name
9630                + " " + r.intent);
9631
9632        final String appName = r.processName;
9633        ProcessRecord app = getProcessRecordLocked(appName, r.appInfo.uid);
9634        if (app != null && app.thread != null) {
9635            try {
9636                realStartServiceLocked(r, app);
9637                return true;
9638            } catch (RemoteException e) {
9639                Log.w(TAG, "Exception when starting service " + r.shortName, e);
9640            }
9641
9642            // If a dead object exception was thrown -- fall through to
9643            // restart the application.
9644        }
9645
9646        if (!mPendingServices.contains(r)) {
9647            // Not running -- get it started, and enqueue this service record
9648            // to be executed when the app comes up.
9649            if (startProcessLocked(appName, r.appInfo, true, intentFlags,
9650                    "service", r.name) == null) {
9651                Log.w(TAG, "Unable to launch app "
9652                        + r.appInfo.packageName + "/"
9653                        + r.appInfo.uid + " for service "
9654                        + r.intent.getIntent() + ": process is bad");
9655                bringDownServiceLocked(r, true);
9656                return false;
9657            }
9658            mPendingServices.add(r);
9659        }
9660        return true;
9661    }
9662
9663    private final void bringDownServiceLocked(ServiceRecord r, boolean force) {
9664        //Log.i(TAG, "Bring down service:");
9665        //r.dump("  ");
9666
9667        // Does it still need to run?
9668        if (!force && r.startRequested) {
9669            return;
9670        }
9671        if (r.connections.size() > 0) {
9672            if (!force) {
9673                // XXX should probably keep a count of the number of auto-create
9674                // connections directly in the service.
9675                Iterator<ConnectionRecord> it = r.connections.values().iterator();
9676                while (it.hasNext()) {
9677                    ConnectionRecord cr = it.next();
9678                    if ((cr.flags&Context.BIND_AUTO_CREATE) != 0) {
9679                        return;
9680                    }
9681                }
9682            }
9683
9684            // Report to all of the connections that the service is no longer
9685            // available.
9686            Iterator<ConnectionRecord> it = r.connections.values().iterator();
9687            while (it.hasNext()) {
9688                ConnectionRecord c = it.next();
9689                try {
9690                    // todo: shouldn't be a synchronous call!
9691                    c.conn.connected(r.name, null);
9692                } catch (Exception e) {
9693                    Log.w(TAG, "Failure disconnecting service " + r.name +
9694                          " to connection " + c.conn.asBinder() +
9695                          " (in " + c.binding.client.processName + ")", e);
9696                }
9697            }
9698        }
9699
9700        // Tell the service that it has been unbound.
9701        if (r.bindings.size() > 0 && r.app != null && r.app.thread != null) {
9702            Iterator<IntentBindRecord> it = r.bindings.values().iterator();
9703            while (it.hasNext()) {
9704                IntentBindRecord ibr = it.next();
9705                if (DEBUG_SERVICE) Log.v(TAG, "Bringing down binding " + ibr
9706                        + ": hasBound=" + ibr.hasBound);
9707                if (r.app != null && r.app.thread != null && ibr.hasBound) {
9708                    try {
9709                        bumpServiceExecutingLocked(r);
9710                        updateOomAdjLocked(r.app);
9711                        ibr.hasBound = false;
9712                        r.app.thread.scheduleUnbindService(r,
9713                                ibr.intent.getIntent());
9714                    } catch (Exception e) {
9715                        Log.w(TAG, "Exception when unbinding service "
9716                                + r.shortName, e);
9717                        serviceDoneExecutingLocked(r, true);
9718                    }
9719                }
9720            }
9721        }
9722
9723        if (DEBUG_SERVICE) Log.v(TAG, "Bringing down service " + r.name
9724                 + " " + r.intent);
9725        EventLog.writeEvent(LOG_AM_DESTROY_SERVICE,
9726                System.identityHashCode(r), r.shortName,
9727                (r.app != null) ? r.app.pid : -1);
9728
9729        mServices.remove(r.name);
9730        mServicesByIntent.remove(r.intent);
9731        if (localLOGV) Log.v(TAG, "BRING DOWN SERVICE: " + r.shortName);
9732        r.totalRestartCount = 0;
9733        unscheduleServiceRestartLocked(r);
9734
9735        // Also make sure it is not on the pending list.
9736        int N = mPendingServices.size();
9737        for (int i=0; i<N; i++) {
9738            if (mPendingServices.get(i) == r) {
9739                mPendingServices.remove(i);
9740                if (DEBUG_SERVICE) Log.v(
9741                    TAG, "Removed pending service: " + r.shortName);
9742                i--;
9743                N--;
9744            }
9745        }
9746
9747        if (r.app != null) {
9748            synchronized (r.stats.getBatteryStats()) {
9749                r.stats.stopLaunchedLocked();
9750            }
9751            r.app.services.remove(r);
9752            if (r.app.thread != null) {
9753                updateServiceForegroundLocked(r.app, false);
9754                try {
9755                    Log.i(TAG, "Stopping service: " + r.shortName);
9756                    bumpServiceExecutingLocked(r);
9757                    mStoppingServices.add(r);
9758                    updateOomAdjLocked(r.app);
9759                    r.app.thread.scheduleStopService(r);
9760                } catch (Exception e) {
9761                    Log.w(TAG, "Exception when stopping service "
9762                            + r.shortName, e);
9763                    serviceDoneExecutingLocked(r, true);
9764                }
9765            } else {
9766                if (DEBUG_SERVICE) Log.v(
9767                    TAG, "Removed service that has no process: " + r.shortName);
9768            }
9769        } else {
9770            if (DEBUG_SERVICE) Log.v(
9771                TAG, "Removed service that is not running: " + r.shortName);
9772        }
9773    }
9774
9775    ComponentName startServiceLocked(IApplicationThread caller,
9776            Intent service, String resolvedType,
9777            int callingPid, int callingUid) {
9778        synchronized(this) {
9779            if (DEBUG_SERVICE) Log.v(TAG, "startService: " + service
9780                    + " type=" + resolvedType + " args=" + service.getExtras());
9781
9782            if (caller != null) {
9783                final ProcessRecord callerApp = getRecordForAppLocked(caller);
9784                if (callerApp == null) {
9785                    throw new SecurityException(
9786                            "Unable to find app for caller " + caller
9787                            + " (pid=" + Binder.getCallingPid()
9788                            + ") when starting service " + service);
9789                }
9790            }
9791
9792            ServiceLookupResult res =
9793                retrieveServiceLocked(service, resolvedType,
9794                        callingPid, callingUid);
9795            if (res == null) {
9796                return null;
9797            }
9798            if (res.record == null) {
9799                return new ComponentName("!", res.permission != null
9800                        ? res.permission : "private to package");
9801            }
9802            ServiceRecord r = res.record;
9803            if (unscheduleServiceRestartLocked(r)) {
9804                if (DEBUG_SERVICE) Log.v(TAG, "START SERVICE WHILE RESTART PENDING: "
9805                        + r.shortName);
9806            }
9807            r.startRequested = true;
9808            r.startArgs.add(service);
9809            r.lastStartId++;
9810            if (r.lastStartId < 1) {
9811                r.lastStartId = 1;
9812            }
9813            r.lastActivity = SystemClock.uptimeMillis();
9814            synchronized (r.stats.getBatteryStats()) {
9815                r.stats.startRunningLocked();
9816            }
9817            if (!bringUpServiceLocked(r, service.getFlags(), false)) {
9818                return new ComponentName("!", "Service process is bad");
9819            }
9820            return r.name;
9821        }
9822    }
9823
9824    public ComponentName startService(IApplicationThread caller, Intent service,
9825            String resolvedType) {
9826        // Refuse possible leaked file descriptors
9827        if (service != null && service.hasFileDescriptors() == true) {
9828            throw new IllegalArgumentException("File descriptors passed in Intent");
9829        }
9830
9831        synchronized(this) {
9832            final int callingPid = Binder.getCallingPid();
9833            final int callingUid = Binder.getCallingUid();
9834            final long origId = Binder.clearCallingIdentity();
9835            ComponentName res = startServiceLocked(caller, service,
9836                    resolvedType, callingPid, callingUid);
9837            Binder.restoreCallingIdentity(origId);
9838            return res;
9839        }
9840    }
9841
9842    ComponentName startServiceInPackage(int uid,
9843            Intent service, String resolvedType) {
9844        synchronized(this) {
9845            final long origId = Binder.clearCallingIdentity();
9846            ComponentName res = startServiceLocked(null, service,
9847                    resolvedType, -1, uid);
9848            Binder.restoreCallingIdentity(origId);
9849            return res;
9850        }
9851    }
9852
9853    public int stopService(IApplicationThread caller, Intent service,
9854            String resolvedType) {
9855        // Refuse possible leaked file descriptors
9856        if (service != null && service.hasFileDescriptors() == true) {
9857            throw new IllegalArgumentException("File descriptors passed in Intent");
9858        }
9859
9860        synchronized(this) {
9861            if (DEBUG_SERVICE) Log.v(TAG, "stopService: " + service
9862                    + " type=" + resolvedType);
9863
9864            final ProcessRecord callerApp = getRecordForAppLocked(caller);
9865            if (caller != null && callerApp == null) {
9866                throw new SecurityException(
9867                        "Unable to find app for caller " + caller
9868                        + " (pid=" + Binder.getCallingPid()
9869                        + ") when stopping service " + service);
9870            }
9871
9872            // If this service is active, make sure it is stopped.
9873            ServiceLookupResult r = findServiceLocked(service, resolvedType);
9874            if (r != null) {
9875                if (r.record != null) {
9876                    synchronized (r.record.stats.getBatteryStats()) {
9877                        r.record.stats.stopRunningLocked();
9878                    }
9879                    r.record.startRequested = false;
9880                    final long origId = Binder.clearCallingIdentity();
9881                    bringDownServiceLocked(r.record, false);
9882                    Binder.restoreCallingIdentity(origId);
9883                    return 1;
9884                }
9885                return -1;
9886            }
9887        }
9888
9889        return 0;
9890    }
9891
9892    public IBinder peekService(Intent service, String resolvedType) {
9893        // Refuse possible leaked file descriptors
9894        if (service != null && service.hasFileDescriptors() == true) {
9895            throw new IllegalArgumentException("File descriptors passed in Intent");
9896        }
9897
9898        IBinder ret = null;
9899
9900        synchronized(this) {
9901            ServiceLookupResult r = findServiceLocked(service, resolvedType);
9902
9903            if (r != null) {
9904                // r.record is null if findServiceLocked() failed the caller permission check
9905                if (r.record == null) {
9906                    throw new SecurityException(
9907                            "Permission Denial: Accessing service " + r.record.name
9908                            + " from pid=" + Binder.getCallingPid()
9909                            + ", uid=" + Binder.getCallingUid()
9910                            + " requires " + r.permission);
9911                }
9912                IntentBindRecord ib = r.record.bindings.get(r.record.intent);
9913                if (ib != null) {
9914                    ret = ib.binder;
9915                }
9916            }
9917        }
9918
9919        return ret;
9920    }
9921
9922    public boolean stopServiceToken(ComponentName className, IBinder token,
9923            int startId) {
9924        synchronized(this) {
9925            if (DEBUG_SERVICE) Log.v(TAG, "stopServiceToken: " + className
9926                    + " " + token + " startId=" + startId);
9927            ServiceRecord r = findServiceLocked(className, token);
9928            if (r != null && (startId < 0 || r.lastStartId == startId)) {
9929                synchronized (r.stats.getBatteryStats()) {
9930                    r.stats.stopRunningLocked();
9931                    r.startRequested = false;
9932                }
9933                final long origId = Binder.clearCallingIdentity();
9934                bringDownServiceLocked(r, false);
9935                Binder.restoreCallingIdentity(origId);
9936                return true;
9937            }
9938        }
9939        return false;
9940    }
9941
9942    public void setServiceForeground(ComponentName className, IBinder token,
9943            boolean isForeground) {
9944        synchronized(this) {
9945            ServiceRecord r = findServiceLocked(className, token);
9946            if (r != null) {
9947                if (r.isForeground != isForeground) {
9948                    final long origId = Binder.clearCallingIdentity();
9949                    r.isForeground = isForeground;
9950                    if (r.app != null) {
9951                        updateServiceForegroundLocked(r.app, true);
9952                    }
9953                    Binder.restoreCallingIdentity(origId);
9954                }
9955            }
9956        }
9957    }
9958
9959    public void updateServiceForegroundLocked(ProcessRecord proc, boolean oomAdj) {
9960        boolean anyForeground = false;
9961        for (ServiceRecord sr : (HashSet<ServiceRecord>)proc.services) {
9962            if (sr.isForeground) {
9963                anyForeground = true;
9964                break;
9965            }
9966        }
9967        if (anyForeground != proc.foregroundServices) {
9968            proc.foregroundServices = anyForeground;
9969            if (oomAdj) {
9970                updateOomAdjLocked();
9971            }
9972        }
9973    }
9974
9975    public int bindService(IApplicationThread caller, IBinder token,
9976            Intent service, String resolvedType,
9977            IServiceConnection connection, int flags) {
9978        // Refuse possible leaked file descriptors
9979        if (service != null && service.hasFileDescriptors() == true) {
9980            throw new IllegalArgumentException("File descriptors passed in Intent");
9981        }
9982
9983        synchronized(this) {
9984            if (DEBUG_SERVICE) Log.v(TAG, "bindService: " + service
9985                    + " type=" + resolvedType + " conn=" + connection.asBinder()
9986                    + " flags=0x" + Integer.toHexString(flags));
9987            final ProcessRecord callerApp = getRecordForAppLocked(caller);
9988            if (callerApp == null) {
9989                throw new SecurityException(
9990                        "Unable to find app for caller " + caller
9991                        + " (pid=" + Binder.getCallingPid()
9992                        + ") when binding service " + service);
9993            }
9994
9995            HistoryRecord activity = null;
9996            if (token != null) {
9997                int aindex = indexOfTokenLocked(token, false);
9998                if (aindex < 0) {
9999                    Log.w(TAG, "Binding with unknown activity: " + token);
10000                    return 0;
10001                }
10002                activity = (HistoryRecord)mHistory.get(aindex);
10003            }
10004
10005            ServiceLookupResult res =
10006                retrieveServiceLocked(service, resolvedType,
10007                        Binder.getCallingPid(), Binder.getCallingUid());
10008            if (res == null) {
10009                return 0;
10010            }
10011            if (res.record == null) {
10012                return -1;
10013            }
10014            ServiceRecord s = res.record;
10015
10016            final long origId = Binder.clearCallingIdentity();
10017
10018            if (unscheduleServiceRestartLocked(s)) {
10019                if (DEBUG_SERVICE) Log.v(TAG, "BIND SERVICE WHILE RESTART PENDING: "
10020                        + s.shortName);
10021            }
10022
10023            AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
10024            ConnectionRecord c = new ConnectionRecord(b, activity,
10025                    connection, flags);
10026
10027            IBinder binder = connection.asBinder();
10028            s.connections.put(binder, c);
10029            b.connections.add(c);
10030            if (activity != null) {
10031                if (activity.connections == null) {
10032                    activity.connections = new HashSet<ConnectionRecord>();
10033                }
10034                activity.connections.add(c);
10035            }
10036            b.client.connections.add(c);
10037            mServiceConnections.put(binder, c);
10038
10039            if ((flags&Context.BIND_AUTO_CREATE) != 0) {
10040                s.lastActivity = SystemClock.uptimeMillis();
10041                if (!bringUpServiceLocked(s, service.getFlags(), false)) {
10042                    return 0;
10043                }
10044            }
10045
10046            if (s.app != null) {
10047                // This could have made the service more important.
10048                updateOomAdjLocked(s.app);
10049            }
10050
10051            if (DEBUG_SERVICE) Log.v(TAG, "Bind " + s + " with " + b
10052                    + ": received=" + b.intent.received
10053                    + " apps=" + b.intent.apps.size()
10054                    + " doRebind=" + b.intent.doRebind);
10055
10056            if (s.app != null && b.intent.received) {
10057                // Service is already running, so we can immediately
10058                // publish the connection.
10059                try {
10060                    c.conn.connected(s.name, b.intent.binder);
10061                } catch (Exception e) {
10062                    Log.w(TAG, "Failure sending service " + s.shortName
10063                            + " to connection " + c.conn.asBinder()
10064                            + " (in " + c.binding.client.processName + ")", e);
10065                }
10066
10067                // If this is the first app connected back to this binding,
10068                // and the service had previously asked to be told when
10069                // rebound, then do so.
10070                if (b.intent.apps.size() == 1 && b.intent.doRebind) {
10071                    requestServiceBindingLocked(s, b.intent, true);
10072                }
10073            } else if (!b.intent.requested) {
10074                requestServiceBindingLocked(s, b.intent, false);
10075            }
10076
10077            Binder.restoreCallingIdentity(origId);
10078        }
10079
10080        return 1;
10081    }
10082
10083    private void removeConnectionLocked(
10084        ConnectionRecord c, ProcessRecord skipApp, HistoryRecord skipAct) {
10085        IBinder binder = c.conn.asBinder();
10086        AppBindRecord b = c.binding;
10087        ServiceRecord s = b.service;
10088        s.connections.remove(binder);
10089        b.connections.remove(c);
10090        if (c.activity != null && c.activity != skipAct) {
10091            if (c.activity.connections != null) {
10092                c.activity.connections.remove(c);
10093            }
10094        }
10095        if (b.client != skipApp) {
10096            b.client.connections.remove(c);
10097        }
10098        mServiceConnections.remove(binder);
10099
10100        if (b.connections.size() == 0) {
10101            b.intent.apps.remove(b.client);
10102        }
10103
10104        if (DEBUG_SERVICE) Log.v(TAG, "Disconnecting binding " + b.intent
10105                + ": shouldUnbind=" + b.intent.hasBound);
10106        if (s.app != null && s.app.thread != null && b.intent.apps.size() == 0
10107                && b.intent.hasBound) {
10108            try {
10109                bumpServiceExecutingLocked(s);
10110                updateOomAdjLocked(s.app);
10111                b.intent.hasBound = false;
10112                // Assume the client doesn't want to know about a rebind;
10113                // we will deal with that later if it asks for one.
10114                b.intent.doRebind = false;
10115                s.app.thread.scheduleUnbindService(s, b.intent.intent.getIntent());
10116            } catch (Exception e) {
10117                Log.w(TAG, "Exception when unbinding service " + s.shortName, e);
10118                serviceDoneExecutingLocked(s, true);
10119            }
10120        }
10121
10122        if ((c.flags&Context.BIND_AUTO_CREATE) != 0) {
10123            bringDownServiceLocked(s, false);
10124        }
10125    }
10126
10127    public boolean unbindService(IServiceConnection connection) {
10128        synchronized (this) {
10129            IBinder binder = connection.asBinder();
10130            if (DEBUG_SERVICE) Log.v(TAG, "unbindService: conn=" + binder);
10131            ConnectionRecord r = mServiceConnections.get(binder);
10132            if (r == null) {
10133                Log.w(TAG, "Unbind failed: could not find connection for "
10134                      + connection.asBinder());
10135                return false;
10136            }
10137
10138            final long origId = Binder.clearCallingIdentity();
10139
10140            removeConnectionLocked(r, null, null);
10141
10142            if (r.binding.service.app != null) {
10143                // This could have made the service less important.
10144                updateOomAdjLocked(r.binding.service.app);
10145            }
10146
10147            Binder.restoreCallingIdentity(origId);
10148        }
10149
10150        return true;
10151    }
10152
10153    public void publishService(IBinder token, Intent intent, IBinder service) {
10154        // Refuse possible leaked file descriptors
10155        if (intent != null && intent.hasFileDescriptors() == true) {
10156            throw new IllegalArgumentException("File descriptors passed in Intent");
10157        }
10158
10159        synchronized(this) {
10160            if (!(token instanceof ServiceRecord)) {
10161                throw new IllegalArgumentException("Invalid service token");
10162            }
10163            ServiceRecord r = (ServiceRecord)token;
10164
10165            final long origId = Binder.clearCallingIdentity();
10166
10167            if (DEBUG_SERVICE) Log.v(TAG, "PUBLISHING SERVICE " + r.name
10168                    + " " + intent + ": " + service);
10169            if (r != null) {
10170                Intent.FilterComparison filter
10171                        = new Intent.FilterComparison(intent);
10172                IntentBindRecord b = r.bindings.get(filter);
10173                if (b != null && !b.received) {
10174                    b.binder = service;
10175                    b.requested = true;
10176                    b.received = true;
10177                    if (r.connections.size() > 0) {
10178                        Iterator<ConnectionRecord> it
10179                                = r.connections.values().iterator();
10180                        while (it.hasNext()) {
10181                            ConnectionRecord c = it.next();
10182                            if (!filter.equals(c.binding.intent.intent)) {
10183                                if (DEBUG_SERVICE) Log.v(
10184                                        TAG, "Not publishing to: " + c);
10185                                if (DEBUG_SERVICE) Log.v(
10186                                        TAG, "Bound intent: " + c.binding.intent.intent);
10187                                if (DEBUG_SERVICE) Log.v(
10188                                        TAG, "Published intent: " + intent);
10189                                continue;
10190                            }
10191                            if (DEBUG_SERVICE) Log.v(TAG, "Publishing to: " + c);
10192                            try {
10193                                c.conn.connected(r.name, service);
10194                            } catch (Exception e) {
10195                                Log.w(TAG, "Failure sending service " + r.name +
10196                                      " to connection " + c.conn.asBinder() +
10197                                      " (in " + c.binding.client.processName + ")", e);
10198                            }
10199                        }
10200                    }
10201                }
10202
10203                serviceDoneExecutingLocked(r, mStoppingServices.contains(r));
10204
10205                Binder.restoreCallingIdentity(origId);
10206            }
10207        }
10208    }
10209
10210    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
10211        // Refuse possible leaked file descriptors
10212        if (intent != null && intent.hasFileDescriptors() == true) {
10213            throw new IllegalArgumentException("File descriptors passed in Intent");
10214        }
10215
10216        synchronized(this) {
10217            if (!(token instanceof ServiceRecord)) {
10218                throw new IllegalArgumentException("Invalid service token");
10219            }
10220            ServiceRecord r = (ServiceRecord)token;
10221
10222            final long origId = Binder.clearCallingIdentity();
10223
10224            if (r != null) {
10225                Intent.FilterComparison filter
10226                        = new Intent.FilterComparison(intent);
10227                IntentBindRecord b = r.bindings.get(filter);
10228                if (DEBUG_SERVICE) Log.v(TAG, "unbindFinished in " + r
10229                        + " at " + b + ": apps="
10230                        + (b != null ? b.apps.size() : 0));
10231                if (b != null) {
10232                    if (b.apps.size() > 0) {
10233                        // Applications have already bound since the last
10234                        // unbind, so just rebind right here.
10235                        requestServiceBindingLocked(r, b, true);
10236                    } else {
10237                        // Note to tell the service the next time there is
10238                        // a new client.
10239                        b.doRebind = true;
10240                    }
10241                }
10242
10243                serviceDoneExecutingLocked(r, mStoppingServices.contains(r));
10244
10245                Binder.restoreCallingIdentity(origId);
10246            }
10247        }
10248    }
10249
10250    public void serviceDoneExecuting(IBinder token) {
10251        synchronized(this) {
10252            if (!(token instanceof ServiceRecord)) {
10253                throw new IllegalArgumentException("Invalid service token");
10254            }
10255            ServiceRecord r = (ServiceRecord)token;
10256            boolean inStopping = mStoppingServices.contains(token);
10257            if (r != null) {
10258                if (DEBUG_SERVICE) Log.v(TAG, "DONE EXECUTING SERVICE " + r.name
10259                        + ": nesting=" + r.executeNesting
10260                        + ", inStopping=" + inStopping);
10261                if (r != token) {
10262                    Log.w(TAG, "Done executing service " + r.name
10263                          + " with incorrect token: given " + token
10264                          + ", expected " + r);
10265                    return;
10266                }
10267
10268                final long origId = Binder.clearCallingIdentity();
10269                serviceDoneExecutingLocked(r, inStopping);
10270                Binder.restoreCallingIdentity(origId);
10271            } else {
10272                Log.w(TAG, "Done executing unknown service " + r.name
10273                        + " with token " + token);
10274            }
10275        }
10276    }
10277
10278    public void serviceDoneExecutingLocked(ServiceRecord r, boolean inStopping) {
10279        r.executeNesting--;
10280        if (r.executeNesting <= 0 && r.app != null) {
10281            r.app.executingServices.remove(r);
10282            if (r.app.executingServices.size() == 0) {
10283                mHandler.removeMessages(SERVICE_TIMEOUT_MSG, r.app);
10284            }
10285            if (inStopping) {
10286                mStoppingServices.remove(r);
10287            }
10288            updateOomAdjLocked(r.app);
10289        }
10290    }
10291
10292    void serviceTimeout(ProcessRecord proc) {
10293        synchronized(this) {
10294            if (proc.executingServices.size() == 0 || proc.thread == null) {
10295                return;
10296            }
10297            long maxTime = SystemClock.uptimeMillis() - SERVICE_TIMEOUT;
10298            Iterator<ServiceRecord> it = proc.executingServices.iterator();
10299            ServiceRecord timeout = null;
10300            long nextTime = 0;
10301            while (it.hasNext()) {
10302                ServiceRecord sr = it.next();
10303                if (sr.executingStart < maxTime) {
10304                    timeout = sr;
10305                    break;
10306                }
10307                if (sr.executingStart > nextTime) {
10308                    nextTime = sr.executingStart;
10309                }
10310            }
10311            if (timeout != null && mLRUProcesses.contains(proc)) {
10312                Log.w(TAG, "Timeout executing service: " + timeout);
10313                appNotRespondingLocked(proc, null, "Executing service "
10314                        + timeout.name);
10315            } else {
10316                Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
10317                msg.obj = proc;
10318                mHandler.sendMessageAtTime(msg, nextTime+SERVICE_TIMEOUT);
10319            }
10320        }
10321    }
10322
10323    // =========================================================
10324    // BACKUP AND RESTORE
10325    // =========================================================
10326
10327    // Cause the target app to be launched if necessary and its backup agent
10328    // instantiated.  The backup agent will invoke backupAgentCreated() on the
10329    // activity manager to announce its creation.
10330    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
10331        if (DEBUG_BACKUP) Log.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode);
10332        enforceCallingPermission("android.permission.BACKUP", "startBackupAgent");
10333
10334        synchronized(this) {
10335            // !!! TODO: currently no check here that we're already bound
10336            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
10337            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10338            synchronized (stats) {
10339                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
10340            }
10341
10342            BackupRecord r = new BackupRecord(ss, app, backupMode);
10343            ComponentName hostingName = new ComponentName(app.packageName, app.backupAgentName);
10344            // startProcessLocked() returns existing proc's record if it's already running
10345            ProcessRecord proc = startProcessLocked(app.processName, app,
10346                    false, 0, "backup", hostingName);
10347            if (proc == null) {
10348                Log.e(TAG, "Unable to start backup agent process " + r);
10349                return false;
10350            }
10351
10352            r.app = proc;
10353            mBackupTarget = r;
10354            mBackupAppName = app.packageName;
10355
10356            // Try not to kill the process during backup
10357            updateOomAdjLocked(proc);
10358
10359            // If the process is already attached, schedule the creation of the backup agent now.
10360            // If it is not yet live, this will be done when it attaches to the framework.
10361            if (proc.thread != null) {
10362                if (DEBUG_BACKUP) Log.v(TAG, "Agent proc already running: " + proc);
10363                try {
10364                    proc.thread.scheduleCreateBackupAgent(app, backupMode);
10365                } catch (RemoteException e) {
10366                    // !!! TODO: notify the backup manager that we crashed, or rely on
10367                    // death notices, or...?
10368                }
10369            } else {
10370                if (DEBUG_BACKUP) Log.v(TAG, "Agent proc not running, waiting for attach");
10371            }
10372            // Invariants: at this point, the target app process exists and the application
10373            // is either already running or in the process of coming up.  mBackupTarget and
10374            // mBackupAppName describe the app, so that when it binds back to the AM we
10375            // know that it's scheduled for a backup-agent operation.
10376        }
10377
10378        return true;
10379    }
10380
10381    // A backup agent has just come up
10382    public void backupAgentCreated(String agentPackageName, IBinder agent) {
10383        if (DEBUG_BACKUP) Log.v(TAG, "backupAgentCreated: " + agentPackageName
10384                + " = " + agent);
10385
10386        synchronized(this) {
10387            if (!agentPackageName.equals(mBackupAppName)) {
10388                Log.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
10389                return;
10390            }
10391
10392            long oldIdent = Binder.clearCallingIdentity();
10393            try {
10394                IBackupManager bm = IBackupManager.Stub.asInterface(
10395                        ServiceManager.getService(Context.BACKUP_SERVICE));
10396                bm.agentConnected(agentPackageName, agent);
10397            } catch (RemoteException e) {
10398                // can't happen; the backup manager service is local
10399            } catch (Exception e) {
10400                Log.w(TAG, "Exception trying to deliver BackupAgent binding: ");
10401                e.printStackTrace();
10402            } finally {
10403                Binder.restoreCallingIdentity(oldIdent);
10404            }
10405        }
10406    }
10407
10408    // done with this agent
10409    public void unbindBackupAgent(ApplicationInfo appInfo) {
10410        if (DEBUG_BACKUP) Log.v(TAG, "unbindBackupAgent: " + appInfo);
10411
10412        synchronized(this) {
10413            if (!mBackupAppName.equals(appInfo.packageName)) {
10414                Log.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
10415                return;
10416            }
10417
10418            ProcessRecord proc = mBackupTarget.app;
10419            mBackupTarget = null;
10420            mBackupAppName = null;
10421
10422            // Not backing this app up any more; reset its OOM adjustment
10423            updateOomAdjLocked(proc);
10424
10425            // If the app crashed during backup, 'thread' will be null here
10426            if (proc.thread != null) {
10427                try {
10428                    proc.thread.scheduleDestroyBackupAgent(appInfo);
10429                } catch (Exception e) {
10430                    Log.e(TAG, "Exception when unbinding backup agent:");
10431                    e.printStackTrace();
10432                }
10433            }
10434        }
10435    }
10436    // =========================================================
10437    // BROADCASTS
10438    // =========================================================
10439
10440    private final List getStickies(String action, IntentFilter filter,
10441            List cur) {
10442        final ContentResolver resolver = mContext.getContentResolver();
10443        final ArrayList<Intent> list = mStickyBroadcasts.get(action);
10444        if (list == null) {
10445            return cur;
10446        }
10447        int N = list.size();
10448        for (int i=0; i<N; i++) {
10449            Intent intent = list.get(i);
10450            if (filter.match(resolver, intent, true, TAG) >= 0) {
10451                if (cur == null) {
10452                    cur = new ArrayList<Intent>();
10453                }
10454                cur.add(intent);
10455            }
10456        }
10457        return cur;
10458    }
10459
10460    private final void scheduleBroadcastsLocked() {
10461        if (DEBUG_BROADCAST) Log.v(TAG, "Schedule broadcasts: current="
10462                + mBroadcastsScheduled);
10463
10464        if (mBroadcastsScheduled) {
10465            return;
10466        }
10467        mHandler.sendEmptyMessage(BROADCAST_INTENT_MSG);
10468        mBroadcastsScheduled = true;
10469    }
10470
10471    public Intent registerReceiver(IApplicationThread caller,
10472            IIntentReceiver receiver, IntentFilter filter, String permission) {
10473        synchronized(this) {
10474            ProcessRecord callerApp = null;
10475            if (caller != null) {
10476                callerApp = getRecordForAppLocked(caller);
10477                if (callerApp == null) {
10478                    throw new SecurityException(
10479                            "Unable to find app for caller " + caller
10480                            + " (pid=" + Binder.getCallingPid()
10481                            + ") when registering receiver " + receiver);
10482                }
10483            }
10484
10485            List allSticky = null;
10486
10487            // Look for any matching sticky broadcasts...
10488            Iterator actions = filter.actionsIterator();
10489            if (actions != null) {
10490                while (actions.hasNext()) {
10491                    String action = (String)actions.next();
10492                    allSticky = getStickies(action, filter, allSticky);
10493                }
10494            } else {
10495                allSticky = getStickies(null, filter, allSticky);
10496            }
10497
10498            // The first sticky in the list is returned directly back to
10499            // the client.
10500            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
10501
10502            if (DEBUG_BROADCAST) Log.v(TAG, "Register receiver " + filter
10503                    + ": " + sticky);
10504
10505            if (receiver == null) {
10506                return sticky;
10507            }
10508
10509            ReceiverList rl
10510                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
10511            if (rl == null) {
10512                rl = new ReceiverList(this, callerApp,
10513                        Binder.getCallingPid(),
10514                        Binder.getCallingUid(), receiver);
10515                if (rl.app != null) {
10516                    rl.app.receivers.add(rl);
10517                } else {
10518                    try {
10519                        receiver.asBinder().linkToDeath(rl, 0);
10520                    } catch (RemoteException e) {
10521                        return sticky;
10522                    }
10523                    rl.linkedToDeath = true;
10524                }
10525                mRegisteredReceivers.put(receiver.asBinder(), rl);
10526            }
10527            BroadcastFilter bf = new BroadcastFilter(filter, rl, permission);
10528            rl.add(bf);
10529            if (!bf.debugCheck()) {
10530                Log.w(TAG, "==> For Dynamic broadast");
10531            }
10532            mReceiverResolver.addFilter(bf);
10533
10534            // Enqueue broadcasts for all existing stickies that match
10535            // this filter.
10536            if (allSticky != null) {
10537                ArrayList receivers = new ArrayList();
10538                receivers.add(bf);
10539
10540                int N = allSticky.size();
10541                for (int i=0; i<N; i++) {
10542                    Intent intent = (Intent)allSticky.get(i);
10543                    BroadcastRecord r = new BroadcastRecord(intent, null,
10544                            null, -1, -1, null, receivers, null, 0, null, null,
10545                            false);
10546                    if (mParallelBroadcasts.size() == 0) {
10547                        scheduleBroadcastsLocked();
10548                    }
10549                    mParallelBroadcasts.add(r);
10550                }
10551            }
10552
10553            return sticky;
10554        }
10555    }
10556
10557    public void unregisterReceiver(IIntentReceiver receiver) {
10558        if (DEBUG_BROADCAST) Log.v(TAG, "Unregister receiver: " + receiver);
10559
10560        boolean doNext = false;
10561
10562        synchronized(this) {
10563            ReceiverList rl
10564                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
10565            if (rl != null) {
10566                if (rl.curBroadcast != null) {
10567                    BroadcastRecord r = rl.curBroadcast;
10568                    doNext = finishReceiverLocked(
10569                        receiver.asBinder(), r.resultCode, r.resultData,
10570                        r.resultExtras, r.resultAbort, true);
10571                }
10572
10573                if (rl.app != null) {
10574                    rl.app.receivers.remove(rl);
10575                }
10576                removeReceiverLocked(rl);
10577                if (rl.linkedToDeath) {
10578                    rl.linkedToDeath = false;
10579                    rl.receiver.asBinder().unlinkToDeath(rl, 0);
10580                }
10581            }
10582        }
10583
10584        if (!doNext) {
10585            return;
10586        }
10587
10588        final long origId = Binder.clearCallingIdentity();
10589        processNextBroadcast(false);
10590        trimApplications();
10591        Binder.restoreCallingIdentity(origId);
10592    }
10593
10594    void removeReceiverLocked(ReceiverList rl) {
10595        mRegisteredReceivers.remove(rl.receiver.asBinder());
10596        int N = rl.size();
10597        for (int i=0; i<N; i++) {
10598            mReceiverResolver.removeFilter(rl.get(i));
10599        }
10600    }
10601
10602    private final int broadcastIntentLocked(ProcessRecord callerApp,
10603            String callerPackage, Intent intent, String resolvedType,
10604            IIntentReceiver resultTo, int resultCode, String resultData,
10605            Bundle map, String requiredPermission,
10606            boolean ordered, boolean sticky, int callingPid, int callingUid) {
10607        intent = new Intent(intent);
10608
10609        if (DEBUG_BROADCAST) Log.v(
10610            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
10611            + " ordered=" + ordered);
10612        if ((resultTo != null) && !ordered) {
10613            Log.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
10614        }
10615
10616        // Handle special intents: if this broadcast is from the package
10617        // manager about a package being removed, we need to remove all of
10618        // its activities from the history stack.
10619        final boolean uidRemoved = intent.ACTION_UID_REMOVED.equals(
10620                intent.getAction());
10621        if (intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
10622                || intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
10623                || uidRemoved) {
10624            if (checkComponentPermission(
10625                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
10626                    callingPid, callingUid, -1)
10627                    == PackageManager.PERMISSION_GRANTED) {
10628                if (uidRemoved) {
10629                    final Bundle intentExtras = intent.getExtras();
10630                    final int uid = intentExtras != null
10631                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
10632                    if (uid >= 0) {
10633                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
10634                        synchronized (bs) {
10635                            bs.removeUidStatsLocked(uid);
10636                        }
10637                    }
10638                } else {
10639                    Uri data = intent.getData();
10640                    String ssp;
10641                    if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
10642                        if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
10643                            uninstallPackageLocked(ssp,
10644                                    intent.getIntExtra(Intent.EXTRA_UID, -1), false);
10645                        }
10646                    }
10647                }
10648            } else {
10649                String msg = "Permission Denial: " + intent.getAction()
10650                        + " broadcast from " + callerPackage + " (pid=" + callingPid
10651                        + ", uid=" + callingUid + ")"
10652                        + " requires "
10653                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
10654                Log.w(TAG, msg);
10655                throw new SecurityException(msg);
10656            }
10657        }
10658
10659        /*
10660         * If this is the time zone changed action, queue up a message that will reset the timezone
10661         * of all currently running processes. This message will get queued up before the broadcast
10662         * happens.
10663         */
10664        if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
10665            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
10666        }
10667
10668        // Add to the sticky list if requested.
10669        if (sticky) {
10670            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
10671                    callingPid, callingUid)
10672                    != PackageManager.PERMISSION_GRANTED) {
10673                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
10674                        + callingPid + ", uid=" + callingUid
10675                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
10676                Log.w(TAG, msg);
10677                throw new SecurityException(msg);
10678            }
10679            if (requiredPermission != null) {
10680                Log.w(TAG, "Can't broadcast sticky intent " + intent
10681                        + " and enforce permission " + requiredPermission);
10682                return BROADCAST_STICKY_CANT_HAVE_PERMISSION;
10683            }
10684            if (intent.getComponent() != null) {
10685                throw new SecurityException(
10686                        "Sticky broadcasts can't target a specific component");
10687            }
10688            ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
10689            if (list == null) {
10690                list = new ArrayList<Intent>();
10691                mStickyBroadcasts.put(intent.getAction(), list);
10692            }
10693            int N = list.size();
10694            int i;
10695            for (i=0; i<N; i++) {
10696                if (intent.filterEquals(list.get(i))) {
10697                    // This sticky already exists, replace it.
10698                    list.set(i, new Intent(intent));
10699                    break;
10700                }
10701            }
10702            if (i >= N) {
10703                list.add(new Intent(intent));
10704            }
10705        }
10706
10707        // Figure out who all will receive this broadcast.
10708        List receivers = null;
10709        List<BroadcastFilter> registeredReceivers = null;
10710        try {
10711            if (intent.getComponent() != null) {
10712                // Broadcast is going to one specific receiver class...
10713                ActivityInfo ai = ActivityThread.getPackageManager().
10714                    getReceiverInfo(intent.getComponent(), STOCK_PM_FLAGS);
10715                if (ai != null) {
10716                    receivers = new ArrayList();
10717                    ResolveInfo ri = new ResolveInfo();
10718                    ri.activityInfo = ai;
10719                    receivers.add(ri);
10720                }
10721            } else {
10722                // Need to resolve the intent to interested receivers...
10723                if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
10724                         == 0) {
10725                    receivers =
10726                        ActivityThread.getPackageManager().queryIntentReceivers(
10727                                intent, resolvedType, STOCK_PM_FLAGS);
10728                }
10729                registeredReceivers = mReceiverResolver.queryIntent(intent, resolvedType, false);
10730            }
10731        } catch (RemoteException ex) {
10732            // pm is in same process, this will never happen.
10733        }
10734
10735        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
10736        if (!ordered && NR > 0) {
10737            // If we are not serializing this broadcast, then send the
10738            // registered receivers separately so they don't wait for the
10739            // components to be launched.
10740            BroadcastRecord r = new BroadcastRecord(intent, callerApp,
10741                    callerPackage, callingPid, callingUid, requiredPermission,
10742                    registeredReceivers, resultTo, resultCode, resultData, map,
10743                    ordered);
10744            if (DEBUG_BROADCAST) Log.v(
10745                    TAG, "Enqueueing parallel broadcast " + r
10746                    + ": prev had " + mParallelBroadcasts.size());
10747            mParallelBroadcasts.add(r);
10748            scheduleBroadcastsLocked();
10749            registeredReceivers = null;
10750            NR = 0;
10751        }
10752
10753        // Merge into one list.
10754        int ir = 0;
10755        if (receivers != null) {
10756            // A special case for PACKAGE_ADDED: do not allow the package
10757            // being added to see this broadcast.  This prevents them from
10758            // using this as a back door to get run as soon as they are
10759            // installed.  Maybe in the future we want to have a special install
10760            // broadcast or such for apps, but we'd like to deliberately make
10761            // this decision.
10762            boolean skip = false;
10763            if (intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
10764                skip = true;
10765            } else if (intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())) {
10766                skip = true;
10767            } else if (intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
10768                skip = true;
10769            }
10770            String skipPackage = (skip && intent.getData() != null)
10771                    ? intent.getData().getSchemeSpecificPart()
10772                    : null;
10773            if (skipPackage != null && receivers != null) {
10774                int NT = receivers.size();
10775                for (int it=0; it<NT; it++) {
10776                    ResolveInfo curt = (ResolveInfo)receivers.get(it);
10777                    if (curt.activityInfo.packageName.equals(skipPackage)) {
10778                        receivers.remove(it);
10779                        it--;
10780                        NT--;
10781                    }
10782                }
10783            }
10784
10785            int NT = receivers != null ? receivers.size() : 0;
10786            int it = 0;
10787            ResolveInfo curt = null;
10788            BroadcastFilter curr = null;
10789            while (it < NT && ir < NR) {
10790                if (curt == null) {
10791                    curt = (ResolveInfo)receivers.get(it);
10792                }
10793                if (curr == null) {
10794                    curr = registeredReceivers.get(ir);
10795                }
10796                if (curr.getPriority() >= curt.priority) {
10797                    // Insert this broadcast record into the final list.
10798                    receivers.add(it, curr);
10799                    ir++;
10800                    curr = null;
10801                    it++;
10802                    NT++;
10803                } else {
10804                    // Skip to the next ResolveInfo in the final list.
10805                    it++;
10806                    curt = null;
10807                }
10808            }
10809        }
10810        while (ir < NR) {
10811            if (receivers == null) {
10812                receivers = new ArrayList();
10813            }
10814            receivers.add(registeredReceivers.get(ir));
10815            ir++;
10816        }
10817
10818        if ((receivers != null && receivers.size() > 0)
10819                || resultTo != null) {
10820            BroadcastRecord r = new BroadcastRecord(intent, callerApp,
10821                    callerPackage, callingPid, callingUid, requiredPermission,
10822                    receivers, resultTo, resultCode, resultData, map, ordered);
10823            if (DEBUG_BROADCAST) Log.v(
10824                    TAG, "Enqueueing ordered broadcast " + r
10825                    + ": prev had " + mOrderedBroadcasts.size());
10826            if (DEBUG_BROADCAST) {
10827                int seq = r.intent.getIntExtra("seq", -1);
10828                Log.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
10829            }
10830            mOrderedBroadcasts.add(r);
10831            scheduleBroadcastsLocked();
10832        }
10833
10834        return BROADCAST_SUCCESS;
10835    }
10836
10837    public final int broadcastIntent(IApplicationThread caller,
10838            Intent intent, String resolvedType, IIntentReceiver resultTo,
10839            int resultCode, String resultData, Bundle map,
10840            String requiredPermission, boolean serialized, boolean sticky) {
10841        // Refuse possible leaked file descriptors
10842        if (intent != null && intent.hasFileDescriptors() == true) {
10843            throw new IllegalArgumentException("File descriptors passed in Intent");
10844        }
10845
10846        synchronized(this) {
10847            if (!mSystemReady) {
10848                // if the caller really truly claims to know what they're doing, go
10849                // ahead and allow the broadcast without launching any receivers
10850                int flags = intent.getFlags();
10851                if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
10852                    intent = new Intent(intent);
10853                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
10854                } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0){
10855                    Log.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
10856                            + " before boot completion");
10857                    throw new IllegalStateException("Cannot broadcast before boot completed");
10858                }
10859            }
10860
10861            final ProcessRecord callerApp = getRecordForAppLocked(caller);
10862            final int callingPid = Binder.getCallingPid();
10863            final int callingUid = Binder.getCallingUid();
10864            final long origId = Binder.clearCallingIdentity();
10865            int res = broadcastIntentLocked(callerApp,
10866                    callerApp != null ? callerApp.info.packageName : null,
10867                    intent, resolvedType, resultTo,
10868                    resultCode, resultData, map, requiredPermission, serialized,
10869                    sticky, callingPid, callingUid);
10870            Binder.restoreCallingIdentity(origId);
10871            return res;
10872        }
10873    }
10874
10875    int broadcastIntentInPackage(String packageName, int uid,
10876            Intent intent, String resolvedType, IIntentReceiver resultTo,
10877            int resultCode, String resultData, Bundle map,
10878            String requiredPermission, boolean serialized, boolean sticky) {
10879        synchronized(this) {
10880            final long origId = Binder.clearCallingIdentity();
10881            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
10882                    resultTo, resultCode, resultData, map, requiredPermission,
10883                    serialized, sticky, -1, uid);
10884            Binder.restoreCallingIdentity(origId);
10885            return res;
10886        }
10887    }
10888
10889    public final void unbroadcastIntent(IApplicationThread caller,
10890            Intent intent) {
10891        // Refuse possible leaked file descriptors
10892        if (intent != null && intent.hasFileDescriptors() == true) {
10893            throw new IllegalArgumentException("File descriptors passed in Intent");
10894        }
10895
10896        synchronized(this) {
10897            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
10898                    != PackageManager.PERMISSION_GRANTED) {
10899                String msg = "Permission Denial: unbroadcastIntent() from pid="
10900                        + Binder.getCallingPid()
10901                        + ", uid=" + Binder.getCallingUid()
10902                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
10903                Log.w(TAG, msg);
10904                throw new SecurityException(msg);
10905            }
10906            ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
10907            if (list != null) {
10908                int N = list.size();
10909                int i;
10910                for (i=0; i<N; i++) {
10911                    if (intent.filterEquals(list.get(i))) {
10912                        list.remove(i);
10913                        break;
10914                    }
10915                }
10916            }
10917        }
10918    }
10919
10920    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
10921            String resultData, Bundle resultExtras, boolean resultAbort,
10922            boolean explicit) {
10923        if (mOrderedBroadcasts.size() == 0) {
10924            if (explicit) {
10925                Log.w(TAG, "finishReceiver called but no pending broadcasts");
10926            }
10927            return false;
10928        }
10929        BroadcastRecord r = mOrderedBroadcasts.get(0);
10930        if (r.receiver == null) {
10931            if (explicit) {
10932                Log.w(TAG, "finishReceiver called but none active");
10933            }
10934            return false;
10935        }
10936        if (r.receiver != receiver) {
10937            Log.w(TAG, "finishReceiver called but active receiver is different");
10938            return false;
10939        }
10940        int state = r.state;
10941        r.state = r.IDLE;
10942        if (state == r.IDLE) {
10943            if (explicit) {
10944                Log.w(TAG, "finishReceiver called but state is IDLE");
10945            }
10946        }
10947        r.receiver = null;
10948        r.intent.setComponent(null);
10949        if (r.curApp != null) {
10950            r.curApp.curReceiver = null;
10951        }
10952        if (r.curFilter != null) {
10953            r.curFilter.receiverList.curBroadcast = null;
10954        }
10955        r.curFilter = null;
10956        r.curApp = null;
10957        r.curComponent = null;
10958        r.curReceiver = null;
10959        mPendingBroadcast = null;
10960
10961        r.resultCode = resultCode;
10962        r.resultData = resultData;
10963        r.resultExtras = resultExtras;
10964        r.resultAbort = resultAbort;
10965
10966        // We will process the next receiver right now if this is finishing
10967        // an app receiver (which is always asynchronous) or after we have
10968        // come back from calling a receiver.
10969        return state == BroadcastRecord.APP_RECEIVE
10970                || state == BroadcastRecord.CALL_DONE_RECEIVE;
10971    }
10972
10973    public void finishReceiver(IBinder who, int resultCode, String resultData,
10974            Bundle resultExtras, boolean resultAbort) {
10975        if (DEBUG_BROADCAST) Log.v(TAG, "Finish receiver: " + who);
10976
10977        // Refuse possible leaked file descriptors
10978        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
10979            throw new IllegalArgumentException("File descriptors passed in Bundle");
10980        }
10981
10982        boolean doNext;
10983
10984        final long origId = Binder.clearCallingIdentity();
10985
10986        synchronized(this) {
10987            doNext = finishReceiverLocked(
10988                who, resultCode, resultData, resultExtras, resultAbort, true);
10989        }
10990
10991        if (doNext) {
10992            processNextBroadcast(false);
10993        }
10994        trimApplications();
10995
10996        Binder.restoreCallingIdentity(origId);
10997    }
10998
10999    private final void logBroadcastReceiverDiscard(BroadcastRecord r) {
11000        if (r.nextReceiver > 0) {
11001            Object curReceiver = r.receivers.get(r.nextReceiver-1);
11002            if (curReceiver instanceof BroadcastFilter) {
11003                BroadcastFilter bf = (BroadcastFilter) curReceiver;
11004                EventLog.writeEvent(LOG_AM_BROADCAST_DISCARD_FILTER,
11005                        System.identityHashCode(r),
11006                        r.intent.getAction(),
11007                        r.nextReceiver - 1,
11008                        System.identityHashCode(bf));
11009            } else {
11010                EventLog.writeEvent(LOG_AM_BROADCAST_DISCARD_APP,
11011                        System.identityHashCode(r),
11012                        r.intent.getAction(),
11013                        r.nextReceiver - 1,
11014                        ((ResolveInfo)curReceiver).toString());
11015            }
11016        } else {
11017            Log.w(TAG, "Discarding broadcast before first receiver is invoked: "
11018                    + r);
11019            EventLog.writeEvent(LOG_AM_BROADCAST_DISCARD_APP,
11020                    System.identityHashCode(r),
11021                    r.intent.getAction(),
11022                    r.nextReceiver,
11023                    "NONE");
11024        }
11025    }
11026
11027    private final void broadcastTimeout() {
11028        synchronized (this) {
11029            if (mOrderedBroadcasts.size() == 0) {
11030                return;
11031            }
11032            long now = SystemClock.uptimeMillis();
11033            BroadcastRecord r = mOrderedBroadcasts.get(0);
11034            if ((r.startTime+BROADCAST_TIMEOUT) > now) {
11035                if (DEBUG_BROADCAST) Log.v(TAG,
11036                        "Premature timeout @ " + now + ": resetting BROADCAST_TIMEOUT_MSG for "
11037                        + (r.startTime + BROADCAST_TIMEOUT));
11038                Message msg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG);
11039                mHandler.sendMessageAtTime(msg, r.startTime+BROADCAST_TIMEOUT);
11040                return;
11041            }
11042
11043            Log.w(TAG, "Timeout of broadcast " + r + " - receiver=" + r.receiver);
11044            r.startTime = now;
11045            r.anrCount++;
11046
11047            // Current receiver has passed its expiration date.
11048            if (r.nextReceiver <= 0) {
11049                Log.w(TAG, "Timeout on receiver with nextReceiver <= 0");
11050                return;
11051            }
11052
11053            ProcessRecord app = null;
11054
11055            Object curReceiver = r.receivers.get(r.nextReceiver-1);
11056            Log.w(TAG, "Receiver during timeout: " + curReceiver);
11057            logBroadcastReceiverDiscard(r);
11058            if (curReceiver instanceof BroadcastFilter) {
11059                BroadcastFilter bf = (BroadcastFilter)curReceiver;
11060                if (bf.receiverList.pid != 0
11061                        && bf.receiverList.pid != MY_PID) {
11062                    synchronized (this.mPidsSelfLocked) {
11063                        app = this.mPidsSelfLocked.get(
11064                                bf.receiverList.pid);
11065                    }
11066                }
11067            } else {
11068                app = r.curApp;
11069            }
11070
11071            if (app != null) {
11072                appNotRespondingLocked(app, null, "Broadcast of " + r.intent.toString());
11073            }
11074
11075            if (mPendingBroadcast == r) {
11076                mPendingBroadcast = null;
11077            }
11078
11079            // Move on to the next receiver.
11080            finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
11081                    r.resultExtras, r.resultAbort, true);
11082            scheduleBroadcastsLocked();
11083        }
11084    }
11085
11086    private final void processCurBroadcastLocked(BroadcastRecord r,
11087            ProcessRecord app) throws RemoteException {
11088        if (app.thread == null) {
11089            throw new RemoteException();
11090        }
11091        r.receiver = app.thread.asBinder();
11092        r.curApp = app;
11093        app.curReceiver = r;
11094        updateLRUListLocked(app, true);
11095
11096        // Tell the application to launch this receiver.
11097        r.intent.setComponent(r.curComponent);
11098
11099        boolean started = false;
11100        try {
11101            if (DEBUG_BROADCAST) Log.v(TAG,
11102                    "Delivering to component " + r.curComponent
11103                    + ": " + r);
11104            app.thread.scheduleReceiver(new Intent(r.intent), r.curReceiver,
11105                    r.resultCode, r.resultData, r.resultExtras, r.ordered);
11106            started = true;
11107        } finally {
11108            if (!started) {
11109                r.receiver = null;
11110                r.curApp = null;
11111                app.curReceiver = null;
11112            }
11113        }
11114
11115    }
11116
11117    static void performReceive(ProcessRecord app, IIntentReceiver receiver,
11118            Intent intent, int resultCode, String data,
11119            Bundle extras, boolean ordered) throws RemoteException {
11120        if (app != null && app.thread != null) {
11121            // If we have an app thread, do the call through that so it is
11122            // correctly ordered with other one-way calls.
11123            app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
11124                    data, extras, ordered);
11125        } else {
11126            receiver.performReceive(intent, resultCode, data, extras, ordered);
11127        }
11128    }
11129
11130    private final void deliverToRegisteredReceiver(BroadcastRecord r,
11131            BroadcastFilter filter, boolean ordered) {
11132        boolean skip = false;
11133        if (filter.requiredPermission != null) {
11134            int perm = checkComponentPermission(filter.requiredPermission,
11135                    r.callingPid, r.callingUid, -1);
11136            if (perm != PackageManager.PERMISSION_GRANTED) {
11137                Log.w(TAG, "Permission Denial: broadcasting "
11138                        + r.intent.toString()
11139                        + " from " + r.callerPackage + " (pid="
11140                        + r.callingPid + ", uid=" + r.callingUid + ")"
11141                        + " requires " + filter.requiredPermission
11142                        + " due to registered receiver " + filter);
11143                skip = true;
11144            }
11145        }
11146        if (r.requiredPermission != null) {
11147            int perm = checkComponentPermission(r.requiredPermission,
11148                    filter.receiverList.pid, filter.receiverList.uid, -1);
11149            if (perm != PackageManager.PERMISSION_GRANTED) {
11150                Log.w(TAG, "Permission Denial: receiving "
11151                        + r.intent.toString()
11152                        + " to " + filter.receiverList.app
11153                        + " (pid=" + filter.receiverList.pid
11154                        + ", uid=" + filter.receiverList.uid + ")"
11155                        + " requires " + r.requiredPermission
11156                        + " due to sender " + r.callerPackage
11157                        + " (uid " + r.callingUid + ")");
11158                skip = true;
11159            }
11160        }
11161
11162        if (!skip) {
11163            // If this is not being sent as an ordered broadcast, then we
11164            // don't want to touch the fields that keep track of the current
11165            // state of ordered broadcasts.
11166            if (ordered) {
11167                r.receiver = filter.receiverList.receiver.asBinder();
11168                r.curFilter = filter;
11169                filter.receiverList.curBroadcast = r;
11170                r.state = BroadcastRecord.CALL_IN_RECEIVE;
11171            }
11172            try {
11173                if (DEBUG_BROADCAST) {
11174                    int seq = r.intent.getIntExtra("seq", -1);
11175                    Log.i(TAG, "Sending broadcast " + r.intent.getAction() + " seq=" + seq
11176                            + " app=" + filter.receiverList.app);
11177                }
11178                performReceive(filter.receiverList.app, filter.receiverList.receiver,
11179                    new Intent(r.intent), r.resultCode,
11180                    r.resultData, r.resultExtras, r.ordered);
11181                if (ordered) {
11182                    r.state = BroadcastRecord.CALL_DONE_RECEIVE;
11183                }
11184            } catch (RemoteException e) {
11185                Log.w(TAG, "Failure sending broadcast " + r.intent, e);
11186                if (ordered) {
11187                    r.receiver = null;
11188                    r.curFilter = null;
11189                    filter.receiverList.curBroadcast = null;
11190                }
11191            }
11192        }
11193    }
11194
11195    private final void processNextBroadcast(boolean fromMsg) {
11196        synchronized(this) {
11197            BroadcastRecord r;
11198
11199            if (DEBUG_BROADCAST) Log.v(TAG, "processNextBroadcast: "
11200                    + mParallelBroadcasts.size() + " broadcasts, "
11201                    + mOrderedBroadcasts.size() + " serialized broadcasts");
11202
11203            updateCpuStats();
11204
11205            if (fromMsg) {
11206                mBroadcastsScheduled = false;
11207            }
11208
11209            // First, deliver any non-serialized broadcasts right away.
11210            while (mParallelBroadcasts.size() > 0) {
11211                r = mParallelBroadcasts.remove(0);
11212                final int N = r.receivers.size();
11213                for (int i=0; i<N; i++) {
11214                    Object target = r.receivers.get(i);
11215                    if (DEBUG_BROADCAST)  Log.v(TAG,
11216                            "Delivering non-serialized to registered "
11217                            + target + ": " + r);
11218                    deliverToRegisteredReceiver(r, (BroadcastFilter)target, false);
11219                }
11220            }
11221
11222            // Now take care of the next serialized one...
11223
11224            // If we are waiting for a process to come up to handle the next
11225            // broadcast, then do nothing at this point.  Just in case, we
11226            // check that the process we're waiting for still exists.
11227            if (mPendingBroadcast != null) {
11228                Log.i(TAG, "processNextBroadcast: waiting for "
11229                        + mPendingBroadcast.curApp);
11230
11231                boolean isDead;
11232                synchronized (mPidsSelfLocked) {
11233                    isDead = (mPidsSelfLocked.get(mPendingBroadcast.curApp.pid) == null);
11234                }
11235                if (!isDead) {
11236                    // It's still alive, so keep waiting
11237                    return;
11238                } else {
11239                    Log.w(TAG, "pending app " + mPendingBroadcast.curApp
11240                            + " died before responding to broadcast");
11241                    mPendingBroadcast = null;
11242                }
11243            }
11244
11245            do {
11246                if (mOrderedBroadcasts.size() == 0) {
11247                    // No more broadcasts pending, so all done!
11248                    scheduleAppGcsLocked();
11249                    return;
11250                }
11251                r = mOrderedBroadcasts.get(0);
11252                boolean forceReceive = false;
11253
11254                // Ensure that even if something goes awry with the timeout
11255                // detection, we catch "hung" broadcasts here, discard them,
11256                // and continue to make progress.
11257                int numReceivers = (r.receivers != null) ? r.receivers.size() : 0;
11258                long now = SystemClock.uptimeMillis();
11259                if (r.dispatchTime > 0) {
11260                    if ((numReceivers > 0) &&
11261                            (now > r.dispatchTime + (2*BROADCAST_TIMEOUT*numReceivers))) {
11262                        Log.w(TAG, "Hung broadcast discarded after timeout failure:"
11263                                + " now=" + now
11264                                + " dispatchTime=" + r.dispatchTime
11265                                + " startTime=" + r.startTime
11266                                + " intent=" + r.intent
11267                                + " numReceivers=" + numReceivers
11268                                + " nextReceiver=" + r.nextReceiver
11269                                + " state=" + r.state);
11270                        broadcastTimeout(); // forcibly finish this broadcast
11271                        forceReceive = true;
11272                        r.state = BroadcastRecord.IDLE;
11273                    }
11274                }
11275
11276                if (r.state != BroadcastRecord.IDLE) {
11277                    if (DEBUG_BROADCAST) Log.d(TAG,
11278                            "processNextBroadcast() called when not idle (state="
11279                            + r.state + ")");
11280                    return;
11281                }
11282
11283                if (r.receivers == null || r.nextReceiver >= numReceivers
11284                        || r.resultAbort || forceReceive) {
11285                    // No more receivers for this broadcast!  Send the final
11286                    // result if requested...
11287                    if (r.resultTo != null) {
11288                        try {
11289                            if (DEBUG_BROADCAST) {
11290                                int seq = r.intent.getIntExtra("seq", -1);
11291                                Log.i(TAG, "Finishing broadcast " + r.intent.getAction()
11292                                        + " seq=" + seq + " app=" + r.callerApp);
11293                            }
11294                            performReceive(r.callerApp, r.resultTo,
11295                                new Intent(r.intent), r.resultCode,
11296                                r.resultData, r.resultExtras, false);
11297                        } catch (RemoteException e) {
11298                            Log.w(TAG, "Failure sending broadcast result of " + r.intent, e);
11299                        }
11300                    }
11301
11302                    if (DEBUG_BROADCAST) Log.v(TAG, "Cancelling BROADCAST_TIMEOUT_MSG");
11303                    mHandler.removeMessages(BROADCAST_TIMEOUT_MSG);
11304
11305                    // ... and on to the next...
11306                    mOrderedBroadcasts.remove(0);
11307                    r = null;
11308                    continue;
11309                }
11310            } while (r == null);
11311
11312            // Get the next receiver...
11313            int recIdx = r.nextReceiver++;
11314
11315            // Keep track of when this receiver started, and make sure there
11316            // is a timeout message pending to kill it if need be.
11317            r.startTime = SystemClock.uptimeMillis();
11318            if (recIdx == 0) {
11319                r.dispatchTime = r.startTime;
11320
11321                if (DEBUG_BROADCAST) Log.v(TAG,
11322                        "Submitting BROADCAST_TIMEOUT_MSG for "
11323                        + (r.startTime + BROADCAST_TIMEOUT));
11324                Message msg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG);
11325                mHandler.sendMessageAtTime(msg, r.startTime+BROADCAST_TIMEOUT);
11326            }
11327
11328            Object nextReceiver = r.receivers.get(recIdx);
11329            if (nextReceiver instanceof BroadcastFilter) {
11330                // Simple case: this is a registered receiver who gets
11331                // a direct call.
11332                BroadcastFilter filter = (BroadcastFilter)nextReceiver;
11333                if (DEBUG_BROADCAST)  Log.v(TAG,
11334                        "Delivering serialized to registered "
11335                        + filter + ": " + r);
11336                deliverToRegisteredReceiver(r, filter, r.ordered);
11337                if (r.receiver == null || !r.ordered) {
11338                    // The receiver has already finished, so schedule to
11339                    // process the next one.
11340                    r.state = BroadcastRecord.IDLE;
11341                    scheduleBroadcastsLocked();
11342                }
11343                return;
11344            }
11345
11346            // Hard case: need to instantiate the receiver, possibly
11347            // starting its application process to host it.
11348
11349            ResolveInfo info =
11350                (ResolveInfo)nextReceiver;
11351
11352            boolean skip = false;
11353            int perm = checkComponentPermission(info.activityInfo.permission,
11354                    r.callingPid, r.callingUid,
11355                    info.activityInfo.exported
11356                            ? -1 : info.activityInfo.applicationInfo.uid);
11357            if (perm != PackageManager.PERMISSION_GRANTED) {
11358                Log.w(TAG, "Permission Denial: broadcasting "
11359                        + r.intent.toString()
11360                        + " from " + r.callerPackage + " (pid=" + r.callingPid
11361                        + ", uid=" + r.callingUid + ")"
11362                        + " requires " + info.activityInfo.permission
11363                        + " due to receiver " + info.activityInfo.packageName
11364                        + "/" + info.activityInfo.name);
11365                skip = true;
11366            }
11367            if (r.callingUid != Process.SYSTEM_UID &&
11368                r.requiredPermission != null) {
11369                try {
11370                    perm = ActivityThread.getPackageManager().
11371                            checkPermission(r.requiredPermission,
11372                                    info.activityInfo.applicationInfo.packageName);
11373                } catch (RemoteException e) {
11374                    perm = PackageManager.PERMISSION_DENIED;
11375                }
11376                if (perm != PackageManager.PERMISSION_GRANTED) {
11377                    Log.w(TAG, "Permission Denial: receiving "
11378                            + r.intent + " to "
11379                            + info.activityInfo.applicationInfo.packageName
11380                            + " requires " + r.requiredPermission
11381                            + " due to sender " + r.callerPackage
11382                            + " (uid " + r.callingUid + ")");
11383                    skip = true;
11384                }
11385            }
11386            if (r.curApp != null && r.curApp.crashing) {
11387                // If the target process is crashing, just skip it.
11388                skip = true;
11389            }
11390
11391            if (skip) {
11392                r.receiver = null;
11393                r.curFilter = null;
11394                r.state = BroadcastRecord.IDLE;
11395                scheduleBroadcastsLocked();
11396                return;
11397            }
11398
11399            r.state = BroadcastRecord.APP_RECEIVE;
11400            String targetProcess = info.activityInfo.processName;
11401            r.curComponent = new ComponentName(
11402                    info.activityInfo.applicationInfo.packageName,
11403                    info.activityInfo.name);
11404            r.curReceiver = info.activityInfo;
11405
11406            // Is this receiver's application already running?
11407            ProcessRecord app = getProcessRecordLocked(targetProcess,
11408                    info.activityInfo.applicationInfo.uid);
11409            if (app != null && app.thread != null) {
11410                try {
11411                    processCurBroadcastLocked(r, app);
11412                    return;
11413                } catch (RemoteException e) {
11414                    Log.w(TAG, "Exception when sending broadcast to "
11415                          + r.curComponent, e);
11416                }
11417
11418                // If a dead object exception was thrown -- fall through to
11419                // restart the application.
11420            }
11421
11422            // Not running -- get it started, and enqueue this history record
11423            // to be executed when the app comes up.
11424            if ((r.curApp=startProcessLocked(targetProcess,
11425                    info.activityInfo.applicationInfo, true,
11426                    r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND,
11427                    "broadcast", r.curComponent)) == null) {
11428                // Ah, this recipient is unavailable.  Finish it if necessary,
11429                // and mark the broadcast record as ready for the next.
11430                Log.w(TAG, "Unable to launch app "
11431                        + info.activityInfo.applicationInfo.packageName + "/"
11432                        + info.activityInfo.applicationInfo.uid + " for broadcast "
11433                        + r.intent + ": process is bad");
11434                logBroadcastReceiverDiscard(r);
11435                finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
11436                        r.resultExtras, r.resultAbort, true);
11437                scheduleBroadcastsLocked();
11438                r.state = BroadcastRecord.IDLE;
11439                return;
11440            }
11441
11442            mPendingBroadcast = r;
11443        }
11444    }
11445
11446    // =========================================================
11447    // INSTRUMENTATION
11448    // =========================================================
11449
11450    public boolean startInstrumentation(ComponentName className,
11451            String profileFile, int flags, Bundle arguments,
11452            IInstrumentationWatcher watcher) {
11453        // Refuse possible leaked file descriptors
11454        if (arguments != null && arguments.hasFileDescriptors()) {
11455            throw new IllegalArgumentException("File descriptors passed in Bundle");
11456        }
11457
11458        synchronized(this) {
11459            InstrumentationInfo ii = null;
11460            ApplicationInfo ai = null;
11461            try {
11462                ii = mContext.getPackageManager().getInstrumentationInfo(
11463                    className, STOCK_PM_FLAGS);
11464                ai = mContext.getPackageManager().getApplicationInfo(
11465                    ii.targetPackage, STOCK_PM_FLAGS);
11466            } catch (PackageManager.NameNotFoundException e) {
11467            }
11468            if (ii == null) {
11469                reportStartInstrumentationFailure(watcher, className,
11470                        "Unable to find instrumentation info for: " + className);
11471                return false;
11472            }
11473            if (ai == null) {
11474                reportStartInstrumentationFailure(watcher, className,
11475                        "Unable to find instrumentation target package: " + ii.targetPackage);
11476                return false;
11477            }
11478
11479            int match = mContext.getPackageManager().checkSignatures(
11480                    ii.targetPackage, ii.packageName);
11481            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
11482                String msg = "Permission Denial: starting instrumentation "
11483                        + className + " from pid="
11484                        + Binder.getCallingPid()
11485                        + ", uid=" + Binder.getCallingPid()
11486                        + " not allowed because package " + ii.packageName
11487                        + " does not have a signature matching the target "
11488                        + ii.targetPackage;
11489                reportStartInstrumentationFailure(watcher, className, msg);
11490                throw new SecurityException(msg);
11491            }
11492
11493            final long origId = Binder.clearCallingIdentity();
11494            uninstallPackageLocked(ii.targetPackage, -1, true);
11495            ProcessRecord app = addAppLocked(ai);
11496            app.instrumentationClass = className;
11497            app.instrumentationInfo = ai;
11498            app.instrumentationProfileFile = profileFile;
11499            app.instrumentationArguments = arguments;
11500            app.instrumentationWatcher = watcher;
11501            app.instrumentationResultClass = className;
11502            Binder.restoreCallingIdentity(origId);
11503        }
11504
11505        return true;
11506    }
11507
11508    /**
11509     * Report errors that occur while attempting to start Instrumentation.  Always writes the
11510     * error to the logs, but if somebody is watching, send the report there too.  This enables
11511     * the "am" command to report errors with more information.
11512     *
11513     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
11514     * @param cn The component name of the instrumentation.
11515     * @param report The error report.
11516     */
11517    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
11518            ComponentName cn, String report) {
11519        Log.w(TAG, report);
11520        try {
11521            if (watcher != null) {
11522                Bundle results = new Bundle();
11523                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
11524                results.putString("Error", report);
11525                watcher.instrumentationStatus(cn, -1, results);
11526            }
11527        } catch (RemoteException e) {
11528            Log.w(TAG, e);
11529        }
11530    }
11531
11532    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
11533        if (app.instrumentationWatcher != null) {
11534            try {
11535                // NOTE:  IInstrumentationWatcher *must* be oneway here
11536                app.instrumentationWatcher.instrumentationFinished(
11537                    app.instrumentationClass,
11538                    resultCode,
11539                    results);
11540            } catch (RemoteException e) {
11541            }
11542        }
11543        app.instrumentationWatcher = null;
11544        app.instrumentationClass = null;
11545        app.instrumentationInfo = null;
11546        app.instrumentationProfileFile = null;
11547        app.instrumentationArguments = null;
11548
11549        uninstallPackageLocked(app.processName, -1, false);
11550    }
11551
11552    public void finishInstrumentation(IApplicationThread target,
11553            int resultCode, Bundle results) {
11554        // Refuse possible leaked file descriptors
11555        if (results != null && results.hasFileDescriptors()) {
11556            throw new IllegalArgumentException("File descriptors passed in Intent");
11557        }
11558
11559        synchronized(this) {
11560            ProcessRecord app = getRecordForAppLocked(target);
11561            if (app == null) {
11562                Log.w(TAG, "finishInstrumentation: no app for " + target);
11563                return;
11564            }
11565            final long origId = Binder.clearCallingIdentity();
11566            finishInstrumentationLocked(app, resultCode, results);
11567            Binder.restoreCallingIdentity(origId);
11568        }
11569    }
11570
11571    // =========================================================
11572    // CONFIGURATION
11573    // =========================================================
11574
11575    public ConfigurationInfo getDeviceConfigurationInfo() {
11576        ConfigurationInfo config = new ConfigurationInfo();
11577        synchronized (this) {
11578            config.reqTouchScreen = mConfiguration.touchscreen;
11579            config.reqKeyboardType = mConfiguration.keyboard;
11580            config.reqNavigation = mConfiguration.navigation;
11581            if (mConfiguration.navigation != Configuration.NAVIGATION_NONAV) {
11582                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
11583            }
11584            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED) {
11585                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
11586            }
11587        }
11588        return config;
11589    }
11590
11591    public Configuration getConfiguration() {
11592        Configuration ci;
11593        synchronized(this) {
11594            ci = new Configuration(mConfiguration);
11595        }
11596        return ci;
11597    }
11598
11599    public void updateConfiguration(Configuration values) {
11600        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
11601                "updateConfiguration()");
11602
11603        synchronized(this) {
11604            if (values == null && mWindowManager != null) {
11605                // sentinel: fetch the current configuration from the window manager
11606                values = mWindowManager.computeNewConfiguration();
11607            }
11608
11609            final long origId = Binder.clearCallingIdentity();
11610            updateConfigurationLocked(values, null);
11611            Binder.restoreCallingIdentity(origId);
11612        }
11613    }
11614
11615    /**
11616     * Do either or both things: (1) change the current configuration, and (2)
11617     * make sure the given activity is running with the (now) current
11618     * configuration.  Returns true if the activity has been left running, or
11619     * false if <var>starting</var> is being destroyed to match the new
11620     * configuration.
11621     */
11622    public boolean updateConfigurationLocked(Configuration values,
11623            HistoryRecord starting) {
11624        int changes = 0;
11625
11626        boolean kept = true;
11627
11628        if (values != null) {
11629            Configuration newConfig = new Configuration(mConfiguration);
11630            changes = newConfig.updateFrom(values);
11631            if (changes != 0) {
11632                if (DEBUG_SWITCH) {
11633                    Log.i(TAG, "Updating configuration to: " + values);
11634                }
11635
11636                EventLog.writeEvent(LOG_CONFIGURATION_CHANGED, changes);
11637
11638                if (values.locale != null) {
11639                    saveLocaleLocked(values.locale,
11640                                     !values.locale.equals(mConfiguration.locale),
11641                                     values.userSetLocale);
11642                }
11643
11644                mConfiguration = newConfig;
11645
11646                Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
11647                msg.obj = new Configuration(mConfiguration);
11648                mHandler.sendMessage(msg);
11649
11650                final int N = mLRUProcesses.size();
11651                for (int i=0; i<N; i++) {
11652                    ProcessRecord app = mLRUProcesses.get(i);
11653                    try {
11654                        if (app.thread != null) {
11655                            app.thread.scheduleConfigurationChanged(mConfiguration);
11656                        }
11657                    } catch (Exception e) {
11658                    }
11659                }
11660                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
11661                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
11662                        null, false, false, MY_PID, Process.SYSTEM_UID);
11663            }
11664        }
11665
11666        if (changes != 0 && starting == null) {
11667            // If the configuration changed, and the caller is not already
11668            // in the process of starting an activity, then find the top
11669            // activity to check if its configuration needs to change.
11670            starting = topRunningActivityLocked(null);
11671        }
11672
11673        if (starting != null) {
11674            kept = ensureActivityConfigurationLocked(starting, changes);
11675            if (kept) {
11676                // If this didn't result in the starting activity being
11677                // destroyed, then we need to make sure at this point that all
11678                // other activities are made visible.
11679                if (DEBUG_SWITCH) Log.i(TAG, "Config didn't destroy " + starting
11680                        + ", ensuring others are correct.");
11681                ensureActivitiesVisibleLocked(starting, changes);
11682            }
11683        }
11684
11685        return kept;
11686    }
11687
11688    private final boolean relaunchActivityLocked(HistoryRecord r,
11689            int changes, boolean andResume) {
11690        List<ResultInfo> results = null;
11691        List<Intent> newIntents = null;
11692        if (andResume) {
11693            results = r.results;
11694            newIntents = r.newIntents;
11695        }
11696        if (DEBUG_SWITCH) Log.v(TAG, "Relaunching: " + r
11697                + " with results=" + results + " newIntents=" + newIntents
11698                + " andResume=" + andResume);
11699        EventLog.writeEvent(andResume ? LOG_AM_RELAUNCH_RESUME_ACTIVITY
11700                : LOG_AM_RELAUNCH_ACTIVITY, System.identityHashCode(r),
11701                r.task.taskId, r.shortComponentName);
11702
11703        r.startFreezingScreenLocked(r.app, 0);
11704
11705        try {
11706            if (DEBUG_SWITCH) Log.i(TAG, "Switch is restarting resumed " + r);
11707            r.app.thread.scheduleRelaunchActivity(r, results, newIntents,
11708                    changes, !andResume);
11709            // Note: don't need to call pauseIfSleepingLocked() here, because
11710            // the caller will only pass in 'andResume' if this activity is
11711            // currently resumed, which implies we aren't sleeping.
11712        } catch (RemoteException e) {
11713            return false;
11714        }
11715
11716        if (andResume) {
11717            r.results = null;
11718            r.newIntents = null;
11719        }
11720
11721        return true;
11722    }
11723
11724    /**
11725     * Make sure the given activity matches the current configuration.  Returns
11726     * false if the activity had to be destroyed.  Returns true if the
11727     * configuration is the same, or the activity will remain running as-is
11728     * for whatever reason.  Ensures the HistoryRecord is updated with the
11729     * correct configuration and all other bookkeeping is handled.
11730     */
11731    private final boolean ensureActivityConfigurationLocked(HistoryRecord r,
11732            int globalChanges) {
11733        if (DEBUG_SWITCH) Log.i(TAG, "Ensuring correct configuration: " + r);
11734
11735        // Short circuit: if the two configurations are the exact same
11736        // object (the common case), then there is nothing to do.
11737        Configuration newConfig = mConfiguration;
11738        if (r.configuration == newConfig) {
11739            if (DEBUG_SWITCH) Log.i(TAG, "Configuration unchanged in " + r);
11740            return true;
11741        }
11742
11743        // We don't worry about activities that are finishing.
11744        if (r.finishing) {
11745            if (DEBUG_SWITCH) Log.i(TAG,
11746                    "Configuration doesn't matter in finishing " + r);
11747            r.stopFreezingScreenLocked(false);
11748            return true;
11749        }
11750
11751        // Okay we now are going to make this activity have the new config.
11752        // But then we need to figure out how it needs to deal with that.
11753        Configuration oldConfig = r.configuration;
11754        r.configuration = newConfig;
11755
11756        // If the activity isn't currently running, just leave the new
11757        // configuration and it will pick that up next time it starts.
11758        if (r.app == null || r.app.thread == null) {
11759            if (DEBUG_SWITCH) Log.i(TAG,
11760                    "Configuration doesn't matter not running " + r);
11761            r.stopFreezingScreenLocked(false);
11762            return true;
11763        }
11764
11765        // If the activity isn't persistent, there is a chance we will
11766        // need to restart it.
11767        if (!r.persistent) {
11768
11769            // Figure out what has changed between the two configurations.
11770            int changes = oldConfig.diff(newConfig);
11771            if (DEBUG_SWITCH) {
11772                Log.i(TAG, "Checking to restart " + r.info.name + ": changed=0x"
11773                        + Integer.toHexString(changes) + ", handles=0x"
11774                        + Integer.toHexString(r.info.configChanges));
11775            }
11776            if ((changes&(~r.info.configChanges)) != 0) {
11777                // Aha, the activity isn't handling the change, so DIE DIE DIE.
11778                r.configChangeFlags |= changes;
11779                r.startFreezingScreenLocked(r.app, globalChanges);
11780                if (r.app == null || r.app.thread == null) {
11781                    if (DEBUG_SWITCH) Log.i(TAG, "Switch is destroying non-running " + r);
11782                    destroyActivityLocked(r, true);
11783                } else if (r.state == ActivityState.PAUSING) {
11784                    // A little annoying: we are waiting for this activity to
11785                    // finish pausing.  Let's not do anything now, but just
11786                    // flag that it needs to be restarted when done pausing.
11787                    r.configDestroy = true;
11788                    return true;
11789                } else if (r.state == ActivityState.RESUMED) {
11790                    // Try to optimize this case: the configuration is changing
11791                    // and we need to restart the top, resumed activity.
11792                    // Instead of doing the normal handshaking, just say
11793                    // "restart!".
11794                    if (DEBUG_SWITCH) Log.i(TAG, "Switch is restarting resumed " + r);
11795                    relaunchActivityLocked(r, r.configChangeFlags, true);
11796                    r.configChangeFlags = 0;
11797                } else {
11798                    if (DEBUG_SWITCH) Log.i(TAG, "Switch is restarting non-resumed " + r);
11799                    relaunchActivityLocked(r, r.configChangeFlags, false);
11800                    r.configChangeFlags = 0;
11801                }
11802
11803                // All done...  tell the caller we weren't able to keep this
11804                // activity around.
11805                return false;
11806            }
11807        }
11808
11809        // Default case: the activity can handle this new configuration, so
11810        // hand it over.  Note that we don't need to give it the new
11811        // configuration, since we always send configuration changes to all
11812        // process when they happen so it can just use whatever configuration
11813        // it last got.
11814        if (r.app != null && r.app.thread != null) {
11815            try {
11816                r.app.thread.scheduleActivityConfigurationChanged(r);
11817            } catch (RemoteException e) {
11818                // If process died, whatever.
11819            }
11820        }
11821        r.stopFreezingScreenLocked(false);
11822
11823        return true;
11824    }
11825
11826    /**
11827     * Save the locale.  You must be inside a synchronized (this) block.
11828     */
11829    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
11830        if(isDiff) {
11831            SystemProperties.set("user.language", l.getLanguage());
11832            SystemProperties.set("user.region", l.getCountry());
11833        }
11834
11835        if(isPersist) {
11836            SystemProperties.set("persist.sys.language", l.getLanguage());
11837            SystemProperties.set("persist.sys.country", l.getCountry());
11838            SystemProperties.set("persist.sys.localevar", l.getVariant());
11839        }
11840    }
11841
11842    // =========================================================
11843    // LIFETIME MANAGEMENT
11844    // =========================================================
11845
11846    private final int computeOomAdjLocked(
11847        ProcessRecord app, int hiddenAdj, ProcessRecord TOP_APP) {
11848        if (mAdjSeq == app.adjSeq) {
11849            // This adjustment has already been computed.
11850            return app.curAdj;
11851        }
11852
11853        if (app.thread == null) {
11854            app.adjSeq = mAdjSeq;
11855            return (app.curAdj=EMPTY_APP_ADJ);
11856        }
11857
11858        app.isForeground = false;
11859
11860        // Determine the importance of the process, starting with most
11861        // important to least, and assign an appropriate OOM adjustment.
11862        int adj;
11863        int N;
11864        if (app == TOP_APP || app.instrumentationClass != null
11865                || app.persistentActivities > 0) {
11866            // The last app on the list is the foreground app.
11867            adj = FOREGROUND_APP_ADJ;
11868            app.isForeground = true;
11869        } else if (app.curReceiver != null ||
11870                (mPendingBroadcast != null && mPendingBroadcast.curApp == app)) {
11871            // An app that is currently receiving a broadcast also
11872            // counts as being in the foreground.
11873            adj = FOREGROUND_APP_ADJ;
11874        } else if (app.executingServices.size() > 0) {
11875            // An app that is currently executing a service callback also
11876            // counts as being in the foreground.
11877            adj = FOREGROUND_APP_ADJ;
11878        } else if (app.foregroundServices || app.forcingToForeground != null) {
11879            // The user is aware of this app, so make it visible.
11880            adj = VISIBLE_APP_ADJ;
11881        } else if (app == mHomeProcess) {
11882            // This process is hosting what we currently consider to be the
11883            // home app, so we don't want to let it go into the background.
11884            adj = HOME_APP_ADJ;
11885        } else if ((N=app.activities.size()) != 0) {
11886            // This app is in the background with paused activities.
11887            adj = hiddenAdj;
11888            for (int j=0; j<N; j++) {
11889                if (((HistoryRecord)app.activities.get(j)).visible) {
11890                    // This app has a visible activity!
11891                    adj = VISIBLE_APP_ADJ;
11892                    break;
11893                }
11894            }
11895        } else {
11896            // A very not-needed process.
11897            adj = EMPTY_APP_ADJ;
11898        }
11899
11900        // By default, we use the computed adjustment.  It may be changed if
11901        // there are applications dependent on our services or providers, but
11902        // this gives us a baseline and makes sure we don't get into an
11903        // infinite recursion.
11904        app.adjSeq = mAdjSeq;
11905        app.curRawAdj = adj;
11906        app.curAdj = adj <= app.maxAdj ? adj : app.maxAdj;
11907
11908        if (mBackupTarget != null && app == mBackupTarget.app) {
11909            // If possible we want to avoid killing apps while they're being backed up
11910            if (adj > BACKUP_APP_ADJ) {
11911                if (DEBUG_BACKUP) Log.v(TAG, "oom BACKUP_APP_ADJ for " + app);
11912                adj = BACKUP_APP_ADJ;
11913            }
11914        }
11915
11916        if (app.services.size() != 0 && adj > FOREGROUND_APP_ADJ) {
11917            // If this process has active services running in it, we would
11918            // like to avoid killing it unless it would prevent the current
11919            // application from running.
11920            if (adj > hiddenAdj) {
11921                adj = hiddenAdj;
11922            }
11923            final long now = SystemClock.uptimeMillis();
11924            // This process is more important if the top activity is
11925            // bound to the service.
11926            Iterator jt = app.services.iterator();
11927            while (jt.hasNext() && adj > FOREGROUND_APP_ADJ) {
11928                ServiceRecord s = (ServiceRecord)jt.next();
11929                if (s.startRequested) {
11930                    if (now < (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
11931                        // This service has seen some activity within
11932                        // recent memory, so we will keep its process ahead
11933                        // of the background processes.
11934                        if (adj > SECONDARY_SERVER_ADJ) {
11935                            adj = SECONDARY_SERVER_ADJ;
11936                        }
11937                    } else {
11938                        // This service has been inactive for too long, just
11939                        // put it with the rest of the background processes.
11940                        if (adj > hiddenAdj) {
11941                            adj = hiddenAdj;
11942                        }
11943                    }
11944                }
11945                if (s.connections.size() > 0 && adj > FOREGROUND_APP_ADJ) {
11946                    Iterator<ConnectionRecord> kt
11947                            = s.connections.values().iterator();
11948                    while (kt.hasNext() && adj > FOREGROUND_APP_ADJ) {
11949                        // XXX should compute this based on the max of
11950                        // all connected clients.
11951                        ConnectionRecord cr = kt.next();
11952                        if (cr.binding.client == app) {
11953                            // Binding to ourself is not interesting.
11954                            continue;
11955                        }
11956                        if ((cr.flags&Context.BIND_AUTO_CREATE) != 0) {
11957                            ProcessRecord client = cr.binding.client;
11958                            int myHiddenAdj = hiddenAdj;
11959                            if (myHiddenAdj > client.hiddenAdj) {
11960                                if (client.hiddenAdj > VISIBLE_APP_ADJ) {
11961                                    myHiddenAdj = client.hiddenAdj;
11962                                } else {
11963                                    myHiddenAdj = VISIBLE_APP_ADJ;
11964                                }
11965                            }
11966                            int clientAdj = computeOomAdjLocked(
11967                                client, myHiddenAdj, TOP_APP);
11968                            if (adj > clientAdj) {
11969                                adj = clientAdj > VISIBLE_APP_ADJ
11970                                        ? clientAdj : VISIBLE_APP_ADJ;
11971                            }
11972                        }
11973                        HistoryRecord a = cr.activity;
11974                        //if (a != null) {
11975                        //    Log.i(TAG, "Connection to " + a ": state=" + a.state);
11976                        //}
11977                        if (a != null && adj > FOREGROUND_APP_ADJ &&
11978                                (a.state == ActivityState.RESUMED
11979                                 || a.state == ActivityState.PAUSING)) {
11980                            adj = FOREGROUND_APP_ADJ;
11981                        }
11982                    }
11983                }
11984            }
11985        }
11986
11987        if (app.pubProviders.size() != 0 && adj > FOREGROUND_APP_ADJ) {
11988            // If this process has published any content providers, then
11989            // its adjustment makes it at least as important as any of the
11990            // processes using those providers, and no less important than
11991            // CONTENT_PROVIDER_ADJ, which is just shy of EMPTY.
11992            if (adj > CONTENT_PROVIDER_ADJ) {
11993                adj = CONTENT_PROVIDER_ADJ;
11994            }
11995            Iterator jt = app.pubProviders.values().iterator();
11996            while (jt.hasNext() && adj > FOREGROUND_APP_ADJ) {
11997                ContentProviderRecord cpr = (ContentProviderRecord)jt.next();
11998                if (cpr.clients.size() != 0) {
11999                    Iterator<ProcessRecord> kt = cpr.clients.iterator();
12000                    while (kt.hasNext() && adj > FOREGROUND_APP_ADJ) {
12001                        ProcessRecord client = kt.next();
12002                        if (client == app) {
12003                            // Being our own client is not interesting.
12004                            continue;
12005                        }
12006                        int myHiddenAdj = hiddenAdj;
12007                        if (myHiddenAdj > client.hiddenAdj) {
12008                            if (client.hiddenAdj > FOREGROUND_APP_ADJ) {
12009                                myHiddenAdj = client.hiddenAdj;
12010                            } else {
12011                                myHiddenAdj = FOREGROUND_APP_ADJ;
12012                            }
12013                        }
12014                        int clientAdj = computeOomAdjLocked(
12015                            client, myHiddenAdj, TOP_APP);
12016                        if (adj > clientAdj) {
12017                            adj = clientAdj > FOREGROUND_APP_ADJ
12018                            ? clientAdj : FOREGROUND_APP_ADJ;
12019                        }
12020                    }
12021                }
12022                // If the provider has external (non-framework) process
12023                // dependencies, ensure that its adjustment is at least
12024                // FOREGROUND_APP_ADJ.
12025                if (cpr.externals != 0) {
12026                    if (adj > FOREGROUND_APP_ADJ) {
12027                        adj = FOREGROUND_APP_ADJ;
12028                    }
12029                }
12030            }
12031        }
12032
12033        app.curRawAdj = adj;
12034
12035        //Log.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
12036        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
12037        if (adj > app.maxAdj) {
12038            adj = app.maxAdj;
12039        }
12040
12041        app.curAdj = adj;
12042        app.curSchedGroup = (adj > VISIBLE_APP_ADJ && !app.persistent)
12043                ? Process.THREAD_GROUP_BG_NONINTERACTIVE
12044                : Process.THREAD_GROUP_DEFAULT;
12045
12046        return adj;
12047    }
12048
12049    /**
12050     * Ask a given process to GC right now.
12051     */
12052    final void performAppGcLocked(ProcessRecord app) {
12053        try {
12054            app.lastRequestedGc = SystemClock.uptimeMillis();
12055            if (app.thread != null) {
12056                app.thread.processInBackground();
12057            }
12058        } catch (Exception e) {
12059            // whatever.
12060        }
12061    }
12062
12063    /**
12064     * Returns true if things are idle enough to perform GCs.
12065     */
12066    private final boolean canGcNow() {
12067        return mParallelBroadcasts.size() == 0
12068                && mOrderedBroadcasts.size() == 0
12069                && (mSleeping || (mResumedActivity != null &&
12070                        mResumedActivity.idle));
12071    }
12072
12073    /**
12074     * Perform GCs on all processes that are waiting for it, but only
12075     * if things are idle.
12076     */
12077    final void performAppGcsLocked() {
12078        final int N = mProcessesToGc.size();
12079        if (N <= 0) {
12080            return;
12081        }
12082        if (canGcNow()) {
12083            while (mProcessesToGc.size() > 0) {
12084                ProcessRecord proc = mProcessesToGc.remove(0);
12085                if (proc.curRawAdj > VISIBLE_APP_ADJ) {
12086                    // To avoid spamming the system, we will GC processes one
12087                    // at a time, waiting a few seconds between each.
12088                    performAppGcLocked(proc);
12089                    scheduleAppGcsLocked();
12090                    return;
12091                }
12092            }
12093        }
12094    }
12095
12096    /**
12097     * If all looks good, perform GCs on all processes waiting for them.
12098     */
12099    final void performAppGcsIfAppropriateLocked() {
12100        if (canGcNow()) {
12101            performAppGcsLocked();
12102            return;
12103        }
12104        // Still not idle, wait some more.
12105        scheduleAppGcsLocked();
12106    }
12107
12108    /**
12109     * Schedule the execution of all pending app GCs.
12110     */
12111    final void scheduleAppGcsLocked() {
12112        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
12113        Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
12114        mHandler.sendMessageDelayed(msg, GC_TIMEOUT);
12115    }
12116
12117    /**
12118     * Set up to ask a process to GC itself.  This will either do it
12119     * immediately, or put it on the list of processes to gc the next
12120     * time things are idle.
12121     */
12122    final void scheduleAppGcLocked(ProcessRecord app) {
12123        long now = SystemClock.uptimeMillis();
12124        if ((app.lastRequestedGc+5000) > now) {
12125            return;
12126        }
12127        if (!mProcessesToGc.contains(app)) {
12128            mProcessesToGc.add(app);
12129            scheduleAppGcsLocked();
12130        }
12131    }
12132
12133    private final boolean updateOomAdjLocked(
12134        ProcessRecord app, int hiddenAdj, ProcessRecord TOP_APP) {
12135        app.hiddenAdj = hiddenAdj;
12136
12137        if (app.thread == null) {
12138            return true;
12139        }
12140
12141        int adj = computeOomAdjLocked(app, hiddenAdj, TOP_APP);
12142
12143        //Log.i(TAG, "Computed adj " + adj + " for app " + app.processName);
12144        //Thread priority adjustment is disabled out to see
12145        //how the kernel scheduler performs.
12146        if (false) {
12147            if (app.pid != 0 && app.isForeground != app.setIsForeground) {
12148                app.setIsForeground = app.isForeground;
12149                if (app.pid != MY_PID) {
12150                    if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Log.v(TAG, "Setting priority of " + app
12151                            + " to " + (app.isForeground
12152                            ? Process.THREAD_PRIORITY_FOREGROUND
12153                            : Process.THREAD_PRIORITY_DEFAULT));
12154                    try {
12155                        Process.setThreadPriority(app.pid, app.isForeground
12156                                ? Process.THREAD_PRIORITY_FOREGROUND
12157                                : Process.THREAD_PRIORITY_DEFAULT);
12158                    } catch (RuntimeException e) {
12159                        Log.w(TAG, "Exception trying to set priority of application thread "
12160                                + app.pid, e);
12161                    }
12162                }
12163            }
12164        }
12165        if (app.pid != 0 && app.pid != MY_PID) {
12166            if (app.curRawAdj != app.setRawAdj) {
12167                if (app.curRawAdj > FOREGROUND_APP_ADJ
12168                        && app.setRawAdj <= FOREGROUND_APP_ADJ) {
12169                    // If this app is transitioning from foreground to
12170                    // non-foreground, have it do a gc.
12171                    scheduleAppGcLocked(app);
12172                } else if (app.curRawAdj >= HIDDEN_APP_MIN_ADJ
12173                        && app.setRawAdj < HIDDEN_APP_MIN_ADJ) {
12174                    // Likewise do a gc when an app is moving in to the
12175                    // background (such as a service stopping).
12176                    scheduleAppGcLocked(app);
12177                }
12178                app.setRawAdj = app.curRawAdj;
12179            }
12180            if (adj != app.setAdj) {
12181                if (Process.setOomAdj(app.pid, adj)) {
12182                    if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Log.v(
12183                        TAG, "Set app " + app.processName +
12184                        " oom adj to " + adj);
12185                    app.setAdj = adj;
12186                } else {
12187                    return false;
12188                }
12189            }
12190            if (app.setSchedGroup != app.curSchedGroup) {
12191                app.setSchedGroup = app.curSchedGroup;
12192                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Log.v(TAG,
12193                        "Setting process group of " + app.processName
12194                        + " to " + app.curSchedGroup);
12195                if (true) {
12196                    long oldId = Binder.clearCallingIdentity();
12197                    try {
12198                        Process.setProcessGroup(app.pid, app.curSchedGroup);
12199                    } catch (Exception e) {
12200                        Log.w(TAG, "Failed setting process group of " + app.pid
12201                                + " to " + app.curSchedGroup);
12202                        e.printStackTrace();
12203                    } finally {
12204                        Binder.restoreCallingIdentity(oldId);
12205                    }
12206                }
12207                if (false) {
12208                    if (app.thread != null) {
12209                        try {
12210                            app.thread.setSchedulingGroup(app.curSchedGroup);
12211                        } catch (RemoteException e) {
12212                        }
12213                    }
12214                }
12215            }
12216        }
12217
12218        return true;
12219    }
12220
12221    private final HistoryRecord resumedAppLocked() {
12222        HistoryRecord resumedActivity = mResumedActivity;
12223        if (resumedActivity == null || resumedActivity.app == null) {
12224            resumedActivity = mPausingActivity;
12225            if (resumedActivity == null || resumedActivity.app == null) {
12226                resumedActivity = topRunningActivityLocked(null);
12227            }
12228        }
12229        return resumedActivity;
12230    }
12231
12232    private final boolean updateOomAdjLocked(ProcessRecord app) {
12233        final HistoryRecord TOP_ACT = resumedAppLocked();
12234        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
12235        int curAdj = app.curAdj;
12236        final boolean wasHidden = app.curAdj >= HIDDEN_APP_MIN_ADJ
12237            && app.curAdj <= HIDDEN_APP_MAX_ADJ;
12238
12239        mAdjSeq++;
12240
12241        final boolean res = updateOomAdjLocked(app, app.hiddenAdj, TOP_APP);
12242        if (res) {
12243            final boolean nowHidden = app.curAdj >= HIDDEN_APP_MIN_ADJ
12244                && app.curAdj <= HIDDEN_APP_MAX_ADJ;
12245            if (nowHidden != wasHidden) {
12246                // Changed to/from hidden state, so apps after it in the LRU
12247                // list may also be changed.
12248                updateOomAdjLocked();
12249            }
12250        }
12251        return res;
12252    }
12253
12254    private final boolean updateOomAdjLocked() {
12255        boolean didOomAdj = true;
12256        final HistoryRecord TOP_ACT = resumedAppLocked();
12257        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
12258
12259        if (false) {
12260            RuntimeException e = new RuntimeException();
12261            e.fillInStackTrace();
12262            Log.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
12263        }
12264
12265        mAdjSeq++;
12266
12267        // First try updating the OOM adjustment for each of the
12268        // application processes based on their current state.
12269        int i = mLRUProcesses.size();
12270        int curHiddenAdj = HIDDEN_APP_MIN_ADJ;
12271        while (i > 0) {
12272            i--;
12273            ProcessRecord app = mLRUProcesses.get(i);
12274            if (updateOomAdjLocked(app, curHiddenAdj, TOP_APP)) {
12275                if (curHiddenAdj < HIDDEN_APP_MAX_ADJ
12276                    && app.curAdj == curHiddenAdj) {
12277                    curHiddenAdj++;
12278                }
12279            } else {
12280                didOomAdj = false;
12281            }
12282        }
12283
12284        // todo: for now pretend like OOM ADJ didn't work, because things
12285        // aren't behaving as expected on Linux -- it's not killing processes.
12286        return ENFORCE_PROCESS_LIMIT || mProcessLimit > 0 ? false : didOomAdj;
12287    }
12288
12289    private final void trimApplications() {
12290        synchronized (this) {
12291            int i;
12292
12293            // First remove any unused application processes whose package
12294            // has been removed.
12295            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
12296                final ProcessRecord app = mRemovedProcesses.get(i);
12297                if (app.activities.size() == 0
12298                        && app.curReceiver == null && app.services.size() == 0) {
12299                    Log.i(
12300                        TAG, "Exiting empty application process "
12301                        + app.processName + " ("
12302                        + (app.thread != null ? app.thread.asBinder() : null)
12303                        + ")\n");
12304                    if (app.pid > 0 && app.pid != MY_PID) {
12305                        Process.killProcess(app.pid);
12306                    } else {
12307                        try {
12308                            app.thread.scheduleExit();
12309                        } catch (Exception e) {
12310                            // Ignore exceptions.
12311                        }
12312                    }
12313                    cleanUpApplicationRecordLocked(app, false, -1);
12314                    mRemovedProcesses.remove(i);
12315
12316                    if (app.persistent) {
12317                        if (app.persistent) {
12318                            addAppLocked(app.info);
12319                        }
12320                    }
12321                }
12322            }
12323
12324            // Now try updating the OOM adjustment for each of the
12325            // application processes based on their current state.
12326            // If the setOomAdj() API is not supported, then go with our
12327            // back-up plan...
12328            if (!updateOomAdjLocked()) {
12329
12330                // Count how many processes are running services.
12331                int numServiceProcs = 0;
12332                for (i=mLRUProcesses.size()-1; i>=0; i--) {
12333                    final ProcessRecord app = mLRUProcesses.get(i);
12334
12335                    if (app.persistent || app.services.size() != 0
12336                            || app.curReceiver != null
12337                            || app.persistentActivities > 0) {
12338                        // Don't count processes holding services against our
12339                        // maximum process count.
12340                        if (localLOGV) Log.v(
12341                            TAG, "Not trimming app " + app + " with services: "
12342                            + app.services);
12343                        numServiceProcs++;
12344                    }
12345                }
12346
12347                int curMaxProcs = mProcessLimit;
12348                if (curMaxProcs <= 0) curMaxProcs = MAX_PROCESSES;
12349                if (mAlwaysFinishActivities) {
12350                    curMaxProcs = 1;
12351                }
12352                curMaxProcs += numServiceProcs;
12353
12354                // Quit as many processes as we can to get down to the desired
12355                // process count.  First remove any processes that no longer
12356                // have activites running in them.
12357                for (   i=0;
12358                        i<mLRUProcesses.size()
12359                            && mLRUProcesses.size() > curMaxProcs;
12360                        i++) {
12361                    final ProcessRecord app = mLRUProcesses.get(i);
12362                    // Quit an application only if it is not currently
12363                    // running any activities.
12364                    if (!app.persistent && app.activities.size() == 0
12365                            && app.curReceiver == null && app.services.size() == 0) {
12366                        Log.i(
12367                            TAG, "Exiting empty application process "
12368                            + app.processName + " ("
12369                            + (app.thread != null ? app.thread.asBinder() : null)
12370                            + ")\n");
12371                        if (app.pid > 0 && app.pid != MY_PID) {
12372                            Process.killProcess(app.pid);
12373                        } else {
12374                            try {
12375                                app.thread.scheduleExit();
12376                            } catch (Exception e) {
12377                                // Ignore exceptions.
12378                            }
12379                        }
12380                        // todo: For now we assume the application is not buggy
12381                        // or evil, and will quit as a result of our request.
12382                        // Eventually we need to drive this off of the death
12383                        // notification, and kill the process if it takes too long.
12384                        cleanUpApplicationRecordLocked(app, false, i);
12385                        i--;
12386                    }
12387                }
12388
12389                // If we still have too many processes, now from the least
12390                // recently used process we start finishing activities.
12391                if (Config.LOGV) Log.v(
12392                    TAG, "*** NOW HAVE " + mLRUProcesses.size() +
12393                    " of " + curMaxProcs + " processes");
12394                for (   i=0;
12395                        i<mLRUProcesses.size()
12396                            && mLRUProcesses.size() > curMaxProcs;
12397                        i++) {
12398                    final ProcessRecord app = mLRUProcesses.get(i);
12399                    // Quit the application only if we have a state saved for
12400                    // all of its activities.
12401                    boolean canQuit = !app.persistent && app.curReceiver == null
12402                        && app.services.size() == 0
12403                        && app.persistentActivities == 0;
12404                    int NUMA = app.activities.size();
12405                    int j;
12406                    if (Config.LOGV) Log.v(
12407                        TAG, "Looking to quit " + app.processName);
12408                    for (j=0; j<NUMA && canQuit; j++) {
12409                        HistoryRecord r = (HistoryRecord)app.activities.get(j);
12410                        if (Config.LOGV) Log.v(
12411                            TAG, "  " + r.intent.getComponent().flattenToShortString()
12412                            + ": frozen=" + r.haveState + ", visible=" + r.visible);
12413                        canQuit = (r.haveState || !r.stateNotNeeded)
12414                                && !r.visible && r.stopped;
12415                    }
12416                    if (canQuit) {
12417                        // Finish all of the activities, and then the app itself.
12418                        for (j=0; j<NUMA; j++) {
12419                            HistoryRecord r = (HistoryRecord)app.activities.get(j);
12420                            if (!r.finishing) {
12421                                destroyActivityLocked(r, false);
12422                            }
12423                            r.resultTo = null;
12424                        }
12425                        Log.i(TAG, "Exiting application process "
12426                              + app.processName + " ("
12427                              + (app.thread != null ? app.thread.asBinder() : null)
12428                              + ")\n");
12429                        if (app.pid > 0 && app.pid != MY_PID) {
12430                            Process.killProcess(app.pid);
12431                        } else {
12432                            try {
12433                                app.thread.scheduleExit();
12434                            } catch (Exception e) {
12435                                // Ignore exceptions.
12436                            }
12437                        }
12438                        // todo: For now we assume the application is not buggy
12439                        // or evil, and will quit as a result of our request.
12440                        // Eventually we need to drive this off of the death
12441                        // notification, and kill the process if it takes too long.
12442                        cleanUpApplicationRecordLocked(app, false, i);
12443                        i--;
12444                        //dump();
12445                    }
12446                }
12447
12448            }
12449
12450            int curMaxActivities = MAX_ACTIVITIES;
12451            if (mAlwaysFinishActivities) {
12452                curMaxActivities = 1;
12453            }
12454
12455            // Finally, if there are too many activities now running, try to
12456            // finish as many as we can to get back down to the limit.
12457            for (   i=0;
12458                    i<mLRUActivities.size()
12459                        && mLRUActivities.size() > curMaxActivities;
12460                    i++) {
12461                final HistoryRecord r
12462                    = (HistoryRecord)mLRUActivities.get(i);
12463
12464                // We can finish this one if we have its icicle saved and
12465                // it is not persistent.
12466                if ((r.haveState || !r.stateNotNeeded) && !r.visible
12467                        && r.stopped && !r.persistent && !r.finishing) {
12468                    final int origSize = mLRUActivities.size();
12469                    destroyActivityLocked(r, true);
12470
12471                    // This will remove it from the LRU list, so keep
12472                    // our index at the same value.  Note that this check to
12473                    // see if the size changes is just paranoia -- if
12474                    // something unexpected happens, we don't want to end up
12475                    // in an infinite loop.
12476                    if (origSize > mLRUActivities.size()) {
12477                        i--;
12478                    }
12479                }
12480            }
12481        }
12482    }
12483
12484    /** This method sends the specified signal to each of the persistent apps */
12485    public void signalPersistentProcesses(int sig) throws RemoteException {
12486        if (sig != Process.SIGNAL_USR1) {
12487            throw new SecurityException("Only SIGNAL_USR1 is allowed");
12488        }
12489
12490        synchronized (this) {
12491            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
12492                    != PackageManager.PERMISSION_GRANTED) {
12493                throw new SecurityException("Requires permission "
12494                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
12495            }
12496
12497            for (int i = mLRUProcesses.size() - 1 ; i >= 0 ; i--) {
12498                ProcessRecord r = mLRUProcesses.get(i);
12499                if (r.thread != null && r.persistent) {
12500                    Process.sendSignal(r.pid, sig);
12501                }
12502            }
12503        }
12504    }
12505
12506    public boolean profileControl(String process, boolean start,
12507            String path) throws RemoteException {
12508
12509        synchronized (this) {
12510            // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
12511            // its own permission.
12512            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12513                    != PackageManager.PERMISSION_GRANTED) {
12514                throw new SecurityException("Requires permission "
12515                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12516            }
12517
12518            ProcessRecord proc = null;
12519            try {
12520                int pid = Integer.parseInt(process);
12521                synchronized (mPidsSelfLocked) {
12522                    proc = mPidsSelfLocked.get(pid);
12523                }
12524            } catch (NumberFormatException e) {
12525            }
12526
12527            if (proc == null) {
12528                HashMap<String, SparseArray<ProcessRecord>> all
12529                        = mProcessNames.getMap();
12530                SparseArray<ProcessRecord> procs = all.get(process);
12531                if (procs != null && procs.size() > 0) {
12532                    proc = procs.valueAt(0);
12533                }
12534            }
12535
12536            if (proc == null || proc.thread == null) {
12537                throw new IllegalArgumentException("Unknown process: " + process);
12538            }
12539
12540            boolean isSecure = "1".equals(SystemProperties.get(SYSTEM_SECURE, "0"));
12541            if (isSecure) {
12542                if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12543                    throw new SecurityException("Process not debuggable: " + proc);
12544                }
12545            }
12546
12547            try {
12548                proc.thread.profilerControl(start, path);
12549                return true;
12550            } catch (RemoteException e) {
12551                throw new IllegalStateException("Process disappeared");
12552            }
12553        }
12554    }
12555
12556    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
12557    public void monitor() {
12558        synchronized (this) { }
12559    }
12560}
12561