ActivityManagerService.java revision 03abb8179f0d912e6dabfc0e2b0f129d85066d17
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.server.AttributeCache;
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 dalvik.system.Zygote;
29
30import android.app.Activity;
31import android.app.ActivityManager;
32import android.app.ActivityManagerNative;
33import android.app.ActivityThread;
34import android.app.AlertDialog;
35import android.app.ApplicationErrorReport;
36import android.app.Dialog;
37import android.app.IActivityController;
38import android.app.IActivityWatcher;
39import android.app.IApplicationThread;
40import android.app.IInstrumentationWatcher;
41import android.app.IServiceConnection;
42import android.app.IThumbnailReceiver;
43import android.app.Instrumentation;
44import android.app.Notification;
45import android.app.PendingIntent;
46import android.app.ResultInfo;
47import android.app.Service;
48import android.backup.IBackupManager;
49import android.content.ActivityNotFoundException;
50import android.content.ComponentName;
51import android.content.ContentResolver;
52import android.content.Context;
53import android.content.Intent;
54import android.content.IntentFilter;
55import android.content.IIntentReceiver;
56import android.content.IIntentSender;
57import android.content.IntentSender;
58import android.content.pm.ActivityInfo;
59import android.content.pm.ApplicationInfo;
60import android.content.pm.ConfigurationInfo;
61import android.content.pm.IPackageDataObserver;
62import android.content.pm.IPackageManager;
63import android.content.pm.InstrumentationInfo;
64import android.content.pm.PackageManager;
65import android.content.pm.PathPermission;
66import android.content.pm.ProviderInfo;
67import android.content.pm.ResolveInfo;
68import android.content.pm.ServiceInfo;
69import android.content.res.Configuration;
70import android.graphics.Bitmap;
71import android.net.Uri;
72import android.os.Binder;
73import android.os.Bundle;
74import android.os.Build;
75import android.os.Debug;
76import android.os.DropBoxManager;
77import android.os.Environment;
78import android.os.FileUtils;
79import android.os.Handler;
80import android.os.IBinder;
81import android.os.IPermissionController;
82import android.os.Looper;
83import android.os.Message;
84import android.os.Parcel;
85import android.os.ParcelFileDescriptor;
86import android.os.PowerManager;
87import android.os.Process;
88import android.os.RemoteCallbackList;
89import android.os.RemoteException;
90import android.os.ServiceManager;
91import android.os.SystemClock;
92import android.os.SystemProperties;
93import android.provider.Checkin;
94import android.provider.Settings;
95import android.text.TextUtils;
96import android.util.Config;
97import android.util.EventLog;
98import android.util.Log;
99import android.util.PrintWriterPrinter;
100import android.util.SparseArray;
101import android.view.Gravity;
102import android.view.LayoutInflater;
103import android.view.View;
104import android.view.WindowManager;
105import android.view.WindowManagerPolicy;
106
107import java.io.File;
108import java.io.FileDescriptor;
109import java.io.FileInputStream;
110import java.io.FileNotFoundException;
111import java.io.IOException;
112import java.io.PrintWriter;
113import java.lang.IllegalStateException;
114import java.lang.ref.WeakReference;
115import java.util.ArrayList;
116import java.util.HashMap;
117import java.util.HashSet;
118import java.util.Iterator;
119import java.util.List;
120import java.util.Locale;
121import java.util.Map;
122
123public final class ActivityManagerService extends ActivityManagerNative implements Watchdog.Monitor {
124    static final String TAG = "ActivityManager";
125    static final boolean DEBUG = false;
126    static final boolean localLOGV = DEBUG ? Config.LOGD : Config.LOGV;
127    static final boolean DEBUG_SWITCH = localLOGV || false;
128    static final boolean DEBUG_TASKS = localLOGV || false;
129    static final boolean DEBUG_PAUSE = localLOGV || false;
130    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
131    static final boolean DEBUG_TRANSITION = localLOGV || false;
132    static final boolean DEBUG_BROADCAST = localLOGV || false;
133    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
134    static final boolean DEBUG_SERVICE = localLOGV || false;
135    static final boolean DEBUG_VISBILITY = localLOGV || false;
136    static final boolean DEBUG_PROCESSES = localLOGV || false;
137    static final boolean DEBUG_PROVIDER = localLOGV || false;
138    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
139    static final boolean DEBUG_RESULTS = localLOGV || false;
140    static final boolean DEBUG_BACKUP = localLOGV || false;
141    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
142    static final boolean VALIDATE_TOKENS = false;
143    static final boolean SHOW_ACTIVITY_START_TIME = true;
144
145    // Control over CPU and battery monitoring.
146    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
147    static final boolean MONITOR_CPU_USAGE = true;
148    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
149    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
150    static final boolean MONITOR_THREAD_CPU_USAGE = false;
151
152    // The flags that are set for all calls we make to the package manager.
153    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
154
155    private static final String SYSTEM_SECURE = "ro.secure";
156
157    // This is the maximum number of application processes we would like
158    // to have running.  Due to the asynchronous nature of things, we can
159    // temporarily go beyond this limit.
160    static final int MAX_PROCESSES = 2;
161
162    // Set to false to leave processes running indefinitely, relying on
163    // the kernel killing them as resources are required.
164    static final boolean ENFORCE_PROCESS_LIMIT = false;
165
166    // This is the maximum number of activities that we would like to have
167    // running at a given time.
168    static final int MAX_ACTIVITIES = 20;
169
170    // Maximum number of recent tasks that we can remember.
171    static final int MAX_RECENT_TASKS = 20;
172
173    // Amount of time after a call to stopAppSwitches() during which we will
174    // prevent further untrusted switches from happening.
175    static final long APP_SWITCH_DELAY_TIME = 5*1000;
176
177    // How long until we reset a task when the user returns to it.  Currently
178    // 30 minutes.
179    static final long ACTIVITY_INACTIVE_RESET_TIME = 1000*60*30;
180
181    // Set to true to disable the icon that is shown while a new activity
182    // is being started.
183    static final boolean SHOW_APP_STARTING_ICON = true;
184
185    // How long we wait until giving up on the last activity to pause.  This
186    // is short because it directly impacts the responsiveness of starting the
187    // next activity.
188    static final int PAUSE_TIMEOUT = 500;
189
190    /**
191     * How long we can hold the launch wake lock before giving up.
192     */
193    static final int LAUNCH_TIMEOUT = 10*1000;
194
195    // How long we wait for a launched process to attach to the activity manager
196    // before we decide it's never going to come up for real.
197    static final int PROC_START_TIMEOUT = 10*1000;
198
199    // How long we wait until giving up on the last activity telling us it
200    // is idle.
201    static final int IDLE_TIMEOUT = 10*1000;
202
203    // How long to wait after going idle before forcing apps to GC.
204    static final int GC_TIMEOUT = 5*1000;
205
206    // The minimum amount of time between successive GC requests for a process.
207    static final int GC_MIN_INTERVAL = 60*1000;
208
209    // How long we wait until giving up on an activity telling us it has
210    // finished destroying itself.
211    static final int DESTROY_TIMEOUT = 10*1000;
212
213    // How long we allow a receiver to run before giving up on it.
214    static final int BROADCAST_TIMEOUT = 10*1000;
215
216    // How long we wait for a service to finish executing.
217    static final int SERVICE_TIMEOUT = 20*1000;
218
219    // How long a service needs to be running until restarting its process
220    // is no longer considered to be a relaunch of the service.
221    static final int SERVICE_RESTART_DURATION = 5*1000;
222
223    // How long a service needs to be running until it will start back at
224    // SERVICE_RESTART_DURATION after being killed.
225    static final int SERVICE_RESET_RUN_DURATION = 60*1000;
226
227    // Multiplying factor to increase restart duration time by, for each time
228    // a service is killed before it has run for SERVICE_RESET_RUN_DURATION.
229    static final int SERVICE_RESTART_DURATION_FACTOR = 4;
230
231    // The minimum amount of time between restarting services that we allow.
232    // That is, when multiple services are restarting, we won't allow each
233    // to restart less than this amount of time from the last one.
234    static final int SERVICE_MIN_RESTART_TIME_BETWEEN = 10*1000;
235
236    // Maximum amount of time for there to be no activity on a service before
237    // we consider it non-essential and allow its process to go on the
238    // LRU background list.
239    static final int MAX_SERVICE_INACTIVITY = 30*60*1000;
240
241    // How long we wait until we timeout on key dispatching.
242    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
243
244    // The minimum time we allow between crashes, for us to consider this
245    // application to be bad and stop and its services and reject broadcasts.
246    static final int MIN_CRASH_INTERVAL = 60*1000;
247
248    // How long we wait until we timeout on key dispatching during instrumentation.
249    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
250
251    // OOM adjustments for processes in various states:
252
253    // This is a process without anything currently running in it.  Definitely
254    // the first to go! Value set in system/rootdir/init.rc on startup.
255    // This value is initalized in the constructor, careful when refering to
256    // this static variable externally.
257    static final int EMPTY_APP_ADJ;
258
259    // This is a process only hosting activities that are not visible,
260    // so it can be killed without any disruption. Value set in
261    // system/rootdir/init.rc on startup.
262    static final int HIDDEN_APP_MAX_ADJ;
263    static int HIDDEN_APP_MIN_ADJ;
264
265    // This is a process holding the home application -- we want to try
266    // avoiding killing it, even if it would normally be in the background,
267    // because the user interacts with it so much.
268    static final int HOME_APP_ADJ;
269
270    // This is a process currently hosting a backup operation.  Killing it
271    // is not entirely fatal but is generally a bad idea.
272    static final int BACKUP_APP_ADJ;
273
274    // This is a process holding a secondary server -- killing it will not
275    // have much of an impact as far as the user is concerned. Value set in
276    // system/rootdir/init.rc on startup.
277    static final int SECONDARY_SERVER_ADJ;
278
279    // This is a process only hosting activities that are visible to the
280    // user, so we'd prefer they don't disappear. Value set in
281    // system/rootdir/init.rc on startup.
282    static final int VISIBLE_APP_ADJ;
283
284    // This is the process running the current foreground app.  We'd really
285    // rather not kill it! Value set in system/rootdir/init.rc on startup.
286    static final int FOREGROUND_APP_ADJ;
287
288    // This is a process running a core server, such as telephony.  Definitely
289    // don't want to kill it, but doing so is not completely fatal.
290    static final int CORE_SERVER_ADJ = -12;
291
292    // The system process runs at the default adjustment.
293    static final int SYSTEM_ADJ = -16;
294
295    // Memory pages are 4K.
296    static final int PAGE_SIZE = 4*1024;
297
298    // System property defining error report receiver for system apps
299    static final String SYSTEM_APPS_ERROR_RECEIVER_PROPERTY = "ro.error.receiver.system.apps";
300
301    // System property defining default error report receiver
302    static final String DEFAULT_ERROR_RECEIVER_PROPERTY = "ro.error.receiver.default";
303
304    // Corresponding memory levels for above adjustments.
305    static final int EMPTY_APP_MEM;
306    static final int HIDDEN_APP_MEM;
307    static final int HOME_APP_MEM;
308    static final int BACKUP_APP_MEM;
309    static final int SECONDARY_SERVER_MEM;
310    static final int VISIBLE_APP_MEM;
311    static final int FOREGROUND_APP_MEM;
312
313    // The minimum number of hidden apps we want to be able to keep around,
314    // without empty apps being able to push them out of memory.
315    static final int MIN_HIDDEN_APPS = 2;
316
317    // We put empty content processes after any hidden processes that have
318    // been idle for less than 30 seconds.
319    static final long CONTENT_APP_IDLE_OFFSET = 30*1000;
320
321    // We put empty content processes after any hidden processes that have
322    // been idle for less than 60 seconds.
323    static final long EMPTY_APP_IDLE_OFFSET = 60*1000;
324
325    static {
326        // These values are set in system/rootdir/init.rc on startup.
327        FOREGROUND_APP_ADJ =
328            Integer.valueOf(SystemProperties.get("ro.FOREGROUND_APP_ADJ"));
329        VISIBLE_APP_ADJ =
330            Integer.valueOf(SystemProperties.get("ro.VISIBLE_APP_ADJ"));
331        SECONDARY_SERVER_ADJ =
332            Integer.valueOf(SystemProperties.get("ro.SECONDARY_SERVER_ADJ"));
333        BACKUP_APP_ADJ =
334            Integer.valueOf(SystemProperties.get("ro.BACKUP_APP_ADJ"));
335        HOME_APP_ADJ =
336            Integer.valueOf(SystemProperties.get("ro.HOME_APP_ADJ"));
337        HIDDEN_APP_MIN_ADJ =
338            Integer.valueOf(SystemProperties.get("ro.HIDDEN_APP_MIN_ADJ"));
339        EMPTY_APP_ADJ =
340            Integer.valueOf(SystemProperties.get("ro.EMPTY_APP_ADJ"));
341        HIDDEN_APP_MAX_ADJ = EMPTY_APP_ADJ-1;
342        FOREGROUND_APP_MEM =
343            Integer.valueOf(SystemProperties.get("ro.FOREGROUND_APP_MEM"))*PAGE_SIZE;
344        VISIBLE_APP_MEM =
345            Integer.valueOf(SystemProperties.get("ro.VISIBLE_APP_MEM"))*PAGE_SIZE;
346        SECONDARY_SERVER_MEM =
347            Integer.valueOf(SystemProperties.get("ro.SECONDARY_SERVER_MEM"))*PAGE_SIZE;
348        BACKUP_APP_MEM =
349            Integer.valueOf(SystemProperties.get("ro.BACKUP_APP_MEM"))*PAGE_SIZE;
350        HOME_APP_MEM =
351            Integer.valueOf(SystemProperties.get("ro.HOME_APP_MEM"))*PAGE_SIZE;
352        HIDDEN_APP_MEM =
353            Integer.valueOf(SystemProperties.get("ro.HIDDEN_APP_MEM"))*PAGE_SIZE;
354        EMPTY_APP_MEM =
355            Integer.valueOf(SystemProperties.get("ro.EMPTY_APP_MEM"))*PAGE_SIZE;
356    }
357
358    final int MY_PID;
359
360    static final String[] EMPTY_STRING_ARRAY = new String[0];
361
362    enum ActivityState {
363        INITIALIZING,
364        RESUMED,
365        PAUSING,
366        PAUSED,
367        STOPPING,
368        STOPPED,
369        FINISHING,
370        DESTROYING,
371        DESTROYED
372    }
373
374    /**
375     * The back history of all previous (and possibly still
376     * running) activities.  It contains HistoryRecord objects.
377     */
378    final ArrayList mHistory = new ArrayList();
379
380    /**
381     * Description of a request to start a new activity, which has been held
382     * due to app switches being disabled.
383     */
384    class PendingActivityLaunch {
385        HistoryRecord r;
386        HistoryRecord sourceRecord;
387        Uri[] grantedUriPermissions;
388        int grantedMode;
389        boolean onlyIfNeeded;
390    }
391
392    final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
393            = new ArrayList<PendingActivityLaunch>();
394
395    /**
396     * List of all active broadcasts that are to be executed immediately
397     * (without waiting for another broadcast to finish).  Currently this only
398     * contains broadcasts to registered receivers, to avoid spinning up
399     * a bunch of processes to execute IntentReceiver components.
400     */
401    final ArrayList<BroadcastRecord> mParallelBroadcasts
402            = new ArrayList<BroadcastRecord>();
403
404    /**
405     * List of all active broadcasts that are to be executed one at a time.
406     * The object at the top of the list is the currently activity broadcasts;
407     * those after it are waiting for the top to finish..
408     */
409    final ArrayList<BroadcastRecord> mOrderedBroadcasts
410            = new ArrayList<BroadcastRecord>();
411
412    /**
413     * Historical data of past broadcasts, for debugging.
414     */
415    static final int MAX_BROADCAST_HISTORY = 100;
416    final BroadcastRecord[] mBroadcastHistory
417            = new BroadcastRecord[MAX_BROADCAST_HISTORY];
418
419    /**
420     * Set when we current have a BROADCAST_INTENT_MSG in flight.
421     */
422    boolean mBroadcastsScheduled = false;
423
424    /**
425     * Set to indicate whether to issue an onUserLeaving callback when a
426     * newly launched activity is being brought in front of us.
427     */
428    boolean mUserLeaving = false;
429
430    /**
431     * When we are in the process of pausing an activity, before starting the
432     * next one, this variable holds the activity that is currently being paused.
433     */
434    HistoryRecord mPausingActivity = null;
435
436    /**
437     * Current activity that is resumed, or null if there is none.
438     */
439    HistoryRecord mResumedActivity = null;
440
441    /**
442     * Activity we have told the window manager to have key focus.
443     */
444    HistoryRecord mFocusedActivity = null;
445
446    /**
447     * This is the last activity that we put into the paused state.  This is
448     * used to determine if we need to do an activity transition while sleeping,
449     * when we normally hold the top activity paused.
450     */
451    HistoryRecord mLastPausedActivity = null;
452
453    /**
454     * List of activities that are waiting for a new activity
455     * to become visible before completing whatever operation they are
456     * supposed to do.
457     */
458    final ArrayList mWaitingVisibleActivities = new ArrayList();
459
460    /**
461     * List of activities that are ready to be stopped, but waiting
462     * for the next activity to settle down before doing so.  It contains
463     * HistoryRecord objects.
464     */
465    final ArrayList<HistoryRecord> mStoppingActivities
466            = new ArrayList<HistoryRecord>();
467
468    /**
469     * Animations that for the current transition have requested not to
470     * be considered for the transition animation.
471     */
472    final ArrayList<HistoryRecord> mNoAnimActivities
473            = new ArrayList<HistoryRecord>();
474
475    /**
476     * List of intents that were used to start the most recent tasks.
477     */
478    final ArrayList<TaskRecord> mRecentTasks
479            = new ArrayList<TaskRecord>();
480
481    /**
482     * List of activities that are ready to be finished, but waiting
483     * for the previous activity to settle down before doing so.  It contains
484     * HistoryRecord objects.
485     */
486    final ArrayList mFinishingActivities = new ArrayList();
487
488    /**
489     * All of the applications we currently have running organized by name.
490     * The keys are strings of the application package name (as
491     * returned by the package manager), and the keys are ApplicationRecord
492     * objects.
493     */
494    final ProcessMap<ProcessRecord> mProcessNames
495            = new ProcessMap<ProcessRecord>();
496
497    /**
498     * The last time that various processes have crashed.
499     */
500    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
501
502    /**
503     * Set of applications that we consider to be bad, and will reject
504     * incoming broadcasts from (which the user has no control over).
505     * Processes are added to this set when they have crashed twice within
506     * a minimum amount of time; they are removed from it when they are
507     * later restarted (hopefully due to some user action).  The value is the
508     * time it was added to the list.
509     */
510    final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>();
511
512    /**
513     * All of the processes we currently have running organized by pid.
514     * The keys are the pid running the application.
515     *
516     * <p>NOTE: This object is protected by its own lock, NOT the global
517     * activity manager lock!
518     */
519    final SparseArray<ProcessRecord> mPidsSelfLocked
520            = new SparseArray<ProcessRecord>();
521
522    /**
523     * All of the processes that have been forced to be foreground.  The key
524     * is the pid of the caller who requested it (we hold a death
525     * link on it).
526     */
527    abstract class ForegroundToken implements IBinder.DeathRecipient {
528        int pid;
529        IBinder token;
530    }
531    final SparseArray<ForegroundToken> mForegroundProcesses
532            = new SparseArray<ForegroundToken>();
533
534    /**
535     * List of records for processes that someone had tried to start before the
536     * system was ready.  We don't start them at that point, but ensure they
537     * are started by the time booting is complete.
538     */
539    final ArrayList<ProcessRecord> mProcessesOnHold
540            = new ArrayList<ProcessRecord>();
541
542    /**
543     * List of records for processes that we have started and are waiting
544     * for them to call back.  This is really only needed when running in
545     * single processes mode, in which case we do not have a unique pid for
546     * each process.
547     */
548    final ArrayList<ProcessRecord> mStartingProcesses
549            = new ArrayList<ProcessRecord>();
550
551    /**
552     * List of persistent applications that are in the process
553     * of being started.
554     */
555    final ArrayList<ProcessRecord> mPersistentStartingProcesses
556            = new ArrayList<ProcessRecord>();
557
558    /**
559     * Processes that are being forcibly torn down.
560     */
561    final ArrayList<ProcessRecord> mRemovedProcesses
562            = new ArrayList<ProcessRecord>();
563
564    /**
565     * List of running applications, sorted by recent usage.
566     * The first entry in the list is the least recently used.
567     * It contains ApplicationRecord objects.  This list does NOT include
568     * any persistent application records (since we never want to exit them).
569     */
570    final ArrayList<ProcessRecord> mLruProcesses
571            = new ArrayList<ProcessRecord>();
572
573    /**
574     * List of processes that should gc as soon as things are idle.
575     */
576    final ArrayList<ProcessRecord> mProcessesToGc
577            = new ArrayList<ProcessRecord>();
578
579    /**
580     * This is the process holding what we currently consider to be
581     * the "home" activity.
582     */
583    private ProcessRecord mHomeProcess;
584
585    /**
586     * List of running activities, sorted by recent usage.
587     * The first entry in the list is the least recently used.
588     * It contains HistoryRecord objects.
589     */
590    private final ArrayList mLRUActivities = new ArrayList();
591
592    /**
593     * Set of PendingResultRecord objects that are currently active.
594     */
595    final HashSet mPendingResultRecords = new HashSet();
596
597    /**
598     * Set of IntentSenderRecord objects that are currently active.
599     */
600    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
601            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
602
603    /**
604     * Intent broadcast that we have tried to start, but are
605     * waiting for its application's process to be created.  We only
606     * need one (instead of a list) because we always process broadcasts
607     * one at a time, so no others can be started while waiting for this
608     * one.
609     */
610    BroadcastRecord mPendingBroadcast = null;
611
612    /**
613     * Keeps track of all IIntentReceivers that have been registered for
614     * broadcasts.  Hash keys are the receiver IBinder, hash value is
615     * a ReceiverList.
616     */
617    final HashMap mRegisteredReceivers = new HashMap();
618
619    /**
620     * Resolver for broadcast intents to registered receivers.
621     * Holds BroadcastFilter (subclass of IntentFilter).
622     */
623    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
624            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
625        @Override
626        protected boolean allowFilterResult(
627                BroadcastFilter filter, List<BroadcastFilter> dest) {
628            IBinder target = filter.receiverList.receiver.asBinder();
629            for (int i=dest.size()-1; i>=0; i--) {
630                if (dest.get(i).receiverList.receiver.asBinder() == target) {
631                    return false;
632                }
633            }
634            return true;
635        }
636    };
637
638    /**
639     * State of all active sticky broadcasts.  Keys are the action of the
640     * sticky Intent, values are an ArrayList of all broadcasted intents with
641     * that action (which should usually be one).
642     */
643    final HashMap<String, ArrayList<Intent>> mStickyBroadcasts =
644            new HashMap<String, ArrayList<Intent>>();
645
646    /**
647     * All currently running services.
648     */
649    final HashMap<ComponentName, ServiceRecord> mServices =
650        new HashMap<ComponentName, ServiceRecord>();
651
652    /**
653     * All currently running services indexed by the Intent used to start them.
654     */
655    final HashMap<Intent.FilterComparison, ServiceRecord> mServicesByIntent =
656        new HashMap<Intent.FilterComparison, ServiceRecord>();
657
658    /**
659     * All currently bound service connections.  Keys are the IBinder of
660     * the client's IServiceConnection.
661     */
662    final HashMap<IBinder, ConnectionRecord> mServiceConnections
663            = new HashMap<IBinder, ConnectionRecord>();
664
665    /**
666     * List of services that we have been asked to start,
667     * but haven't yet been able to.  It is used to hold start requests
668     * while waiting for their corresponding application thread to get
669     * going.
670     */
671    final ArrayList<ServiceRecord> mPendingServices
672            = new ArrayList<ServiceRecord>();
673
674    /**
675     * List of services that are scheduled to restart following a crash.
676     */
677    final ArrayList<ServiceRecord> mRestartingServices
678            = new ArrayList<ServiceRecord>();
679
680    /**
681     * List of services that are in the process of being stopped.
682     */
683    final ArrayList<ServiceRecord> mStoppingServices
684            = new ArrayList<ServiceRecord>();
685
686    /**
687     * Backup/restore process management
688     */
689    String mBackupAppName = null;
690    BackupRecord mBackupTarget = null;
691
692    /**
693     * List of PendingThumbnailsRecord objects of clients who are still
694     * waiting to receive all of the thumbnails for a task.
695     */
696    final ArrayList mPendingThumbnails = new ArrayList();
697
698    /**
699     * List of HistoryRecord objects that have been finished and must
700     * still report back to a pending thumbnail receiver.
701     */
702    final ArrayList mCancelledThumbnails = new ArrayList();
703
704    /**
705     * All of the currently running global content providers.  Keys are a
706     * string containing the provider name and values are a
707     * ContentProviderRecord object containing the data about it.  Note
708     * that a single provider may be published under multiple names, so
709     * there may be multiple entries here for a single one in mProvidersByClass.
710     */
711    final HashMap mProvidersByName = new HashMap();
712
713    /**
714     * All of the currently running global content providers.  Keys are a
715     * string containing the provider's implementation class and values are a
716     * ContentProviderRecord object containing the data about it.
717     */
718    final HashMap mProvidersByClass = new HashMap();
719
720    /**
721     * List of content providers who have clients waiting for them.  The
722     * application is currently being launched and the provider will be
723     * removed from this list once it is published.
724     */
725    final ArrayList mLaunchingProviders = new ArrayList();
726
727    /**
728     * Global set of specific Uri permissions that have been granted.
729     */
730    final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions
731            = new SparseArray<HashMap<Uri, UriPermission>>();
732
733    /**
734     * Thread-local storage used to carry caller permissions over through
735     * indirect content-provider access.
736     * @see #ActivityManagerService.openContentUri()
737     */
738    private class Identity {
739        public int pid;
740        public int uid;
741
742        Identity(int _pid, int _uid) {
743            pid = _pid;
744            uid = _uid;
745        }
746    }
747    private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
748
749    /**
750     * All information we have collected about the runtime performance of
751     * any user id that can impact battery performance.
752     */
753    final BatteryStatsService mBatteryStatsService;
754
755    /**
756     * information about component usage
757     */
758    final UsageStatsService mUsageStatsService;
759
760    /**
761     * Current configuration information.  HistoryRecord objects are given
762     * a reference to this object to indicate which configuration they are
763     * currently running in, so this object must be kept immutable.
764     */
765    Configuration mConfiguration = new Configuration();
766
767    /**
768     * Hardware-reported OpenGLES version.
769     */
770    final int GL_ES_VERSION;
771
772    /**
773     * List of initialization arguments to pass to all processes when binding applications to them.
774     * For example, references to the commonly used services.
775     */
776    HashMap<String, IBinder> mAppBindArgs;
777
778    /**
779     * Temporary to avoid allocations.  Protected by main lock.
780     */
781    final StringBuilder mStringBuilder = new StringBuilder(256);
782
783    /**
784     * Used to control how we initialize the service.
785     */
786    boolean mStartRunning = false;
787    ComponentName mTopComponent;
788    String mTopAction;
789    String mTopData;
790    boolean mSystemReady = false;
791    boolean mBooting = false;
792    boolean mWaitingUpdate = false;
793    boolean mDidUpdate = false;
794
795    Context mContext;
796
797    int mFactoryTest;
798
799    boolean mCheckedForSetup;
800
801    /**
802     * The time at which we will allow normal application switches again,
803     * after a call to {@link #stopAppSwitches()}.
804     */
805    long mAppSwitchesAllowedTime;
806
807    /**
808     * This is set to true after the first switch after mAppSwitchesAllowedTime
809     * is set; any switches after that will clear the time.
810     */
811    boolean mDidAppSwitch;
812
813    /**
814     * Set while we are wanting to sleep, to prevent any
815     * activities from being started/resumed.
816     */
817    boolean mSleeping = false;
818
819    /**
820     * Set if we are shutting down the system, similar to sleeping.
821     */
822    boolean mShuttingDown = false;
823
824    /**
825     * Set when the system is going to sleep, until we have
826     * successfully paused the current activity and released our wake lock.
827     * At that point the system is allowed to actually sleep.
828     */
829    PowerManager.WakeLock mGoingToSleep;
830
831    /**
832     * We don't want to allow the device to go to sleep while in the process
833     * of launching an activity.  This is primarily to allow alarm intent
834     * receivers to launch an activity and get that to run before the device
835     * goes back to sleep.
836     */
837    PowerManager.WakeLock mLaunchingActivity;
838
839    /**
840     * Task identifier that activities are currently being started
841     * in.  Incremented each time a new task is created.
842     * todo: Replace this with a TokenSpace class that generates non-repeating
843     * integers that won't wrap.
844     */
845    int mCurTask = 1;
846
847    /**
848     * Current sequence id for oom_adj computation traversal.
849     */
850    int mAdjSeq = 0;
851
852    /**
853     * Set to true if the ANDROID_SIMPLE_PROCESS_MANAGEMENT envvar
854     * is set, indicating the user wants processes started in such a way
855     * that they can use ANDROID_PROCESS_WRAPPER and know what will be
856     * running in each process (thus no pre-initialized process, etc).
857     */
858    boolean mSimpleProcessManagement = false;
859
860    /**
861     * System monitoring: number of processes that died since the last
862     * N procs were started.
863     */
864    int[] mProcDeaths = new int[20];
865
866    /**
867     * This is set if we had to do a delayed dexopt of an app before launching
868     * it, to increasing the ANR timeouts in that case.
869     */
870    boolean mDidDexOpt;
871
872    String mDebugApp = null;
873    boolean mWaitForDebugger = false;
874    boolean mDebugTransient = false;
875    String mOrigDebugApp = null;
876    boolean mOrigWaitForDebugger = false;
877    boolean mAlwaysFinishActivities = false;
878    IActivityController mController = null;
879
880    final RemoteCallbackList<IActivityWatcher> mWatchers
881            = new RemoteCallbackList<IActivityWatcher>();
882
883    /**
884     * Callback of last caller to {@link #requestPss}.
885     */
886    Runnable mRequestPssCallback;
887
888    /**
889     * Remaining processes for which we are waiting results from the last
890     * call to {@link #requestPss}.
891     */
892    final ArrayList<ProcessRecord> mRequestPssList
893            = new ArrayList<ProcessRecord>();
894
895    /**
896     * Runtime statistics collection thread.  This object's lock is used to
897     * protect all related state.
898     */
899    final Thread mProcessStatsThread;
900
901    /**
902     * Used to collect process stats when showing not responding dialog.
903     * Protected by mProcessStatsThread.
904     */
905    final ProcessStats mProcessStats = new ProcessStats(
906            MONITOR_THREAD_CPU_USAGE);
907    long mLastCpuTime = 0;
908    long mLastWriteTime = 0;
909
910    long mInitialStartTime = 0;
911
912    /**
913     * Set to true after the system has finished booting.
914     */
915    boolean mBooted = false;
916
917    int mProcessLimit = 0;
918
919    WindowManagerService mWindowManager;
920
921    static ActivityManagerService mSelf;
922    static ActivityThread mSystemThread;
923
924    private final class AppDeathRecipient implements IBinder.DeathRecipient {
925        final ProcessRecord mApp;
926        final int mPid;
927        final IApplicationThread mAppThread;
928
929        AppDeathRecipient(ProcessRecord app, int pid,
930                IApplicationThread thread) {
931            if (localLOGV) Log.v(
932                TAG, "New death recipient " + this
933                + " for thread " + thread.asBinder());
934            mApp = app;
935            mPid = pid;
936            mAppThread = thread;
937        }
938
939        public void binderDied() {
940            if (localLOGV) Log.v(
941                TAG, "Death received in " + this
942                + " for thread " + mAppThread.asBinder());
943            removeRequestedPss(mApp);
944            synchronized(ActivityManagerService.this) {
945                appDiedLocked(mApp, mPid, mAppThread);
946            }
947        }
948    }
949
950    static final int SHOW_ERROR_MSG = 1;
951    static final int SHOW_NOT_RESPONDING_MSG = 2;
952    static final int SHOW_FACTORY_ERROR_MSG = 3;
953    static final int UPDATE_CONFIGURATION_MSG = 4;
954    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
955    static final int WAIT_FOR_DEBUGGER_MSG = 6;
956    static final int BROADCAST_INTENT_MSG = 7;
957    static final int BROADCAST_TIMEOUT_MSG = 8;
958    static final int PAUSE_TIMEOUT_MSG = 9;
959    static final int IDLE_TIMEOUT_MSG = 10;
960    static final int IDLE_NOW_MSG = 11;
961    static final int SERVICE_TIMEOUT_MSG = 12;
962    static final int UPDATE_TIME_ZONE = 13;
963    static final int SHOW_UID_ERROR_MSG = 14;
964    static final int IM_FEELING_LUCKY_MSG = 15;
965    static final int LAUNCH_TIMEOUT_MSG = 16;
966    static final int DESTROY_TIMEOUT_MSG = 17;
967    static final int SERVICE_ERROR_MSG = 18;
968    static final int RESUME_TOP_ACTIVITY_MSG = 19;
969    static final int PROC_START_TIMEOUT_MSG = 20;
970    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
971    static final int KILL_APPLICATION_MSG = 22;
972
973    AlertDialog mUidAlert;
974
975    final Handler mHandler = new Handler() {
976        //public Handler() {
977        //    if (localLOGV) Log.v(TAG, "Handler started!");
978        //}
979
980        public void handleMessage(Message msg) {
981            switch (msg.what) {
982            case SHOW_ERROR_MSG: {
983                HashMap data = (HashMap) msg.obj;
984                synchronized (ActivityManagerService.this) {
985                    ProcessRecord proc = (ProcessRecord)data.get("app");
986                    if (proc != null && proc.crashDialog != null) {
987                        Log.e(TAG, "App already has crash dialog: " + proc);
988                        return;
989                    }
990                    AppErrorResult res = (AppErrorResult) data.get("result");
991                    if (!mSleeping && !mShuttingDown) {
992                        Dialog d = new AppErrorDialog(mContext, res, proc);
993                        d.show();
994                        proc.crashDialog = d;
995                    } else {
996                        // The device is asleep, so just pretend that the user
997                        // saw a crash dialog and hit "force quit".
998                        res.set(0);
999                    }
1000                }
1001
1002                ensureBootCompleted();
1003            } break;
1004            case SHOW_NOT_RESPONDING_MSG: {
1005                synchronized (ActivityManagerService.this) {
1006                    HashMap data = (HashMap) msg.obj;
1007                    ProcessRecord proc = (ProcessRecord)data.get("app");
1008                    if (proc != null && proc.anrDialog != null) {
1009                        Log.e(TAG, "App already has anr dialog: " + proc);
1010                        return;
1011                    }
1012
1013                    broadcastIntentLocked(null, null, new Intent("android.intent.action.ANR"),
1014                            null, null, 0, null, null, null,
1015                            false, false, MY_PID, Process.SYSTEM_UID);
1016
1017                    Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1018                            mContext, proc, (HistoryRecord)data.get("activity"));
1019                    d.show();
1020                    proc.anrDialog = d;
1021                }
1022
1023                ensureBootCompleted();
1024            } break;
1025            case SHOW_FACTORY_ERROR_MSG: {
1026                Dialog d = new FactoryErrorDialog(
1027                    mContext, msg.getData().getCharSequence("msg"));
1028                d.show();
1029                ensureBootCompleted();
1030            } break;
1031            case UPDATE_CONFIGURATION_MSG: {
1032                final ContentResolver resolver = mContext.getContentResolver();
1033                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1034            } break;
1035            case GC_BACKGROUND_PROCESSES_MSG: {
1036                synchronized (ActivityManagerService.this) {
1037                    performAppGcsIfAppropriateLocked();
1038                }
1039            } break;
1040            case WAIT_FOR_DEBUGGER_MSG: {
1041                synchronized (ActivityManagerService.this) {
1042                    ProcessRecord app = (ProcessRecord)msg.obj;
1043                    if (msg.arg1 != 0) {
1044                        if (!app.waitedForDebugger) {
1045                            Dialog d = new AppWaitingForDebuggerDialog(
1046                                    ActivityManagerService.this,
1047                                    mContext, app);
1048                            app.waitDialog = d;
1049                            app.waitedForDebugger = true;
1050                            d.show();
1051                        }
1052                    } else {
1053                        if (app.waitDialog != null) {
1054                            app.waitDialog.dismiss();
1055                            app.waitDialog = null;
1056                        }
1057                    }
1058                }
1059            } break;
1060            case BROADCAST_INTENT_MSG: {
1061                if (DEBUG_BROADCAST) Log.v(
1062                        TAG, "Received BROADCAST_INTENT_MSG");
1063                processNextBroadcast(true);
1064            } break;
1065            case BROADCAST_TIMEOUT_MSG: {
1066                if (mDidDexOpt) {
1067                    mDidDexOpt = false;
1068                    Message nmsg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG);
1069                    mHandler.sendMessageDelayed(nmsg, BROADCAST_TIMEOUT);
1070                    return;
1071                }
1072                broadcastTimeout();
1073            } break;
1074            case PAUSE_TIMEOUT_MSG: {
1075                IBinder token = (IBinder)msg.obj;
1076                // We don't at this point know if the activity is fullscreen,
1077                // so we need to be conservative and assume it isn't.
1078                Log.w(TAG, "Activity pause timeout for " + token);
1079                activityPaused(token, null, true);
1080            } break;
1081            case IDLE_TIMEOUT_MSG: {
1082                if (mDidDexOpt) {
1083                    mDidDexOpt = false;
1084                    Message nmsg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG);
1085                    nmsg.obj = msg.obj;
1086                    mHandler.sendMessageDelayed(nmsg, IDLE_TIMEOUT);
1087                    return;
1088                }
1089                // We don't at this point know if the activity is fullscreen,
1090                // so we need to be conservative and assume it isn't.
1091                IBinder token = (IBinder)msg.obj;
1092                Log.w(TAG, "Activity idle timeout for " + token);
1093                activityIdleInternal(token, true, null);
1094            } break;
1095            case DESTROY_TIMEOUT_MSG: {
1096                IBinder token = (IBinder)msg.obj;
1097                // We don't at this point know if the activity is fullscreen,
1098                // so we need to be conservative and assume it isn't.
1099                Log.w(TAG, "Activity destroy timeout for " + token);
1100                activityDestroyed(token);
1101            } break;
1102            case IDLE_NOW_MSG: {
1103                IBinder token = (IBinder)msg.obj;
1104                activityIdle(token, null);
1105            } break;
1106            case SERVICE_TIMEOUT_MSG: {
1107                if (mDidDexOpt) {
1108                    mDidDexOpt = false;
1109                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1110                    nmsg.obj = msg.obj;
1111                    mHandler.sendMessageDelayed(nmsg, SERVICE_TIMEOUT);
1112                    return;
1113                }
1114                serviceTimeout((ProcessRecord)msg.obj);
1115            } break;
1116            case UPDATE_TIME_ZONE: {
1117                synchronized (ActivityManagerService.this) {
1118                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1119                        ProcessRecord r = mLruProcesses.get(i);
1120                        if (r.thread != null) {
1121                            try {
1122                                r.thread.updateTimeZone();
1123                            } catch (RemoteException ex) {
1124                                Log.w(TAG, "Failed to update time zone for: " + r.info.processName);
1125                            }
1126                        }
1127                    }
1128                }
1129            } break;
1130            case SHOW_UID_ERROR_MSG: {
1131                // XXX This is a temporary dialog, no need to localize.
1132                AlertDialog d = new BaseErrorDialog(mContext);
1133                d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1134                d.setCancelable(false);
1135                d.setTitle("System UIDs Inconsistent");
1136                d.setMessage("UIDs on the system are inconsistent, you need to wipe your data partition or your device will be unstable.");
1137                d.setButton("I'm Feeling Lucky",
1138                        mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1139                mUidAlert = d;
1140                d.show();
1141            } break;
1142            case IM_FEELING_LUCKY_MSG: {
1143                if (mUidAlert != null) {
1144                    mUidAlert.dismiss();
1145                    mUidAlert = null;
1146                }
1147            } break;
1148            case LAUNCH_TIMEOUT_MSG: {
1149                if (mDidDexOpt) {
1150                    mDidDexOpt = false;
1151                    Message nmsg = mHandler.obtainMessage(LAUNCH_TIMEOUT_MSG);
1152                    mHandler.sendMessageDelayed(nmsg, LAUNCH_TIMEOUT);
1153                    return;
1154                }
1155                synchronized (ActivityManagerService.this) {
1156                    if (mLaunchingActivity.isHeld()) {
1157                        Log.w(TAG, "Launch timeout has expired, giving up wake lock!");
1158                        mLaunchingActivity.release();
1159                    }
1160                }
1161            } break;
1162            case SERVICE_ERROR_MSG: {
1163                ServiceRecord srv = (ServiceRecord)msg.obj;
1164                // This needs to be *un*synchronized to avoid deadlock.
1165                Checkin.logEvent(mContext.getContentResolver(),
1166                        Checkin.Events.Tag.SYSTEM_SERVICE_LOOPING,
1167                        srv.name.toShortString());
1168            } break;
1169            case RESUME_TOP_ACTIVITY_MSG: {
1170                synchronized (ActivityManagerService.this) {
1171                    resumeTopActivityLocked(null);
1172                }
1173            } break;
1174            case PROC_START_TIMEOUT_MSG: {
1175                if (mDidDexOpt) {
1176                    mDidDexOpt = false;
1177                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1178                    nmsg.obj = msg.obj;
1179                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1180                    return;
1181                }
1182                ProcessRecord app = (ProcessRecord)msg.obj;
1183                synchronized (ActivityManagerService.this) {
1184                    processStartTimedOutLocked(app);
1185                }
1186            } break;
1187            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1188                synchronized (ActivityManagerService.this) {
1189                    doPendingActivityLaunchesLocked(true);
1190                }
1191            } break;
1192            case KILL_APPLICATION_MSG: {
1193                synchronized (ActivityManagerService.this) {
1194                    int uid = msg.arg1;
1195                    boolean restart = (msg.arg2 == 1);
1196                    String pkg = (String) msg.obj;
1197                    forceStopPackageLocked(pkg, uid, restart);
1198                }
1199            } break;
1200            }
1201        }
1202    };
1203
1204    public static void setSystemProcess() {
1205        try {
1206            ActivityManagerService m = mSelf;
1207
1208            ServiceManager.addService("activity", m);
1209            ServiceManager.addService("meminfo", new MemBinder(m));
1210            if (MONITOR_CPU_USAGE) {
1211                ServiceManager.addService("cpuinfo", new CpuBinder(m));
1212            }
1213            ServiceManager.addService("permission", new PermissionController(m));
1214
1215            ApplicationInfo info =
1216                mSelf.mContext.getPackageManager().getApplicationInfo(
1217                        "android", STOCK_PM_FLAGS);
1218            mSystemThread.installSystemApplicationInfo(info);
1219
1220            synchronized (mSelf) {
1221                ProcessRecord app = mSelf.newProcessRecordLocked(
1222                        mSystemThread.getApplicationThread(), info,
1223                        info.processName);
1224                app.persistent = true;
1225                app.pid = Process.myPid();
1226                app.maxAdj = SYSTEM_ADJ;
1227                mSelf.mProcessNames.put(app.processName, app.info.uid, app);
1228                synchronized (mSelf.mPidsSelfLocked) {
1229                    mSelf.mPidsSelfLocked.put(app.pid, app);
1230                }
1231                mSelf.updateLruProcessLocked(app, true, true);
1232            }
1233        } catch (PackageManager.NameNotFoundException e) {
1234            throw new RuntimeException(
1235                    "Unable to find android system package", e);
1236        }
1237    }
1238
1239    public void setWindowManager(WindowManagerService wm) {
1240        mWindowManager = wm;
1241    }
1242
1243    public static final Context main(int factoryTest) {
1244        AThread thr = new AThread();
1245        thr.start();
1246
1247        synchronized (thr) {
1248            while (thr.mService == null) {
1249                try {
1250                    thr.wait();
1251                } catch (InterruptedException e) {
1252                }
1253            }
1254        }
1255
1256        ActivityManagerService m = thr.mService;
1257        mSelf = m;
1258        ActivityThread at = ActivityThread.systemMain();
1259        mSystemThread = at;
1260        Context context = at.getSystemContext();
1261        m.mContext = context;
1262        m.mFactoryTest = factoryTest;
1263        PowerManager pm =
1264            (PowerManager)context.getSystemService(Context.POWER_SERVICE);
1265        m.mGoingToSleep = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Sleep");
1266        m.mLaunchingActivity = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Launch");
1267        m.mLaunchingActivity.setReferenceCounted(false);
1268
1269        m.mBatteryStatsService.publish(context);
1270        m.mUsageStatsService.publish(context);
1271
1272        synchronized (thr) {
1273            thr.mReady = true;
1274            thr.notifyAll();
1275        }
1276
1277        m.startRunning(null, null, null, null);
1278
1279        return context;
1280    }
1281
1282    public static ActivityManagerService self() {
1283        return mSelf;
1284    }
1285
1286    static class AThread extends Thread {
1287        ActivityManagerService mService;
1288        boolean mReady = false;
1289
1290        public AThread() {
1291            super("ActivityManager");
1292        }
1293
1294        public void run() {
1295            Looper.prepare();
1296
1297            android.os.Process.setThreadPriority(
1298                    android.os.Process.THREAD_PRIORITY_FOREGROUND);
1299
1300            ActivityManagerService m = new ActivityManagerService();
1301
1302            synchronized (this) {
1303                mService = m;
1304                notifyAll();
1305            }
1306
1307            synchronized (this) {
1308                while (!mReady) {
1309                    try {
1310                        wait();
1311                    } catch (InterruptedException e) {
1312                    }
1313                }
1314            }
1315
1316            Looper.loop();
1317        }
1318    }
1319
1320    static class MemBinder extends Binder {
1321        ActivityManagerService mActivityManagerService;
1322        MemBinder(ActivityManagerService activityManagerService) {
1323            mActivityManagerService = activityManagerService;
1324        }
1325
1326        @Override
1327        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1328            ActivityManagerService service = mActivityManagerService;
1329            ArrayList<ProcessRecord> procs;
1330            synchronized (mActivityManagerService) {
1331                if (args != null && args.length > 0
1332                        && args[0].charAt(0) != '-') {
1333                    procs = new ArrayList<ProcessRecord>();
1334                    int pid = -1;
1335                    try {
1336                        pid = Integer.parseInt(args[0]);
1337                    } catch (NumberFormatException e) {
1338
1339                    }
1340                    for (int i=service.mLruProcesses.size()-1; i>=0; i--) {
1341                        ProcessRecord proc = service.mLruProcesses.get(i);
1342                        if (proc.pid == pid) {
1343                            procs.add(proc);
1344                        } else if (proc.processName.equals(args[0])) {
1345                            procs.add(proc);
1346                        }
1347                    }
1348                    if (procs.size() <= 0) {
1349                        pw.println("No process found for: " + args[0]);
1350                        return;
1351                    }
1352                } else {
1353                    procs = service.mLruProcesses;
1354                }
1355            }
1356            dumpApplicationMemoryUsage(fd, pw, procs, "  ", args);
1357        }
1358    }
1359
1360    static class CpuBinder extends Binder {
1361        ActivityManagerService mActivityManagerService;
1362        CpuBinder(ActivityManagerService activityManagerService) {
1363            mActivityManagerService = activityManagerService;
1364        }
1365
1366        @Override
1367        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1368            synchronized (mActivityManagerService.mProcessStatsThread) {
1369                pw.print(mActivityManagerService.mProcessStats.printCurrentState());
1370            }
1371        }
1372    }
1373
1374    private ActivityManagerService() {
1375        String v = System.getenv("ANDROID_SIMPLE_PROCESS_MANAGEMENT");
1376        if (v != null && Integer.getInteger(v) != 0) {
1377            mSimpleProcessManagement = true;
1378        }
1379        v = System.getenv("ANDROID_DEBUG_APP");
1380        if (v != null) {
1381            mSimpleProcessManagement = true;
1382        }
1383
1384        Log.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
1385
1386        MY_PID = Process.myPid();
1387
1388        File dataDir = Environment.getDataDirectory();
1389        File systemDir = new File(dataDir, "system");
1390        systemDir.mkdirs();
1391        mBatteryStatsService = new BatteryStatsService(new File(
1392                systemDir, "batterystats.bin").toString());
1393        mBatteryStatsService.getActiveStatistics().readLocked();
1394        mBatteryStatsService.getActiveStatistics().writeLocked();
1395
1396        mUsageStatsService = new UsageStatsService( new File(
1397                systemDir, "usagestats").toString());
1398
1399        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
1400            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
1401
1402        mConfiguration.makeDefault();
1403        mProcessStats.init();
1404
1405        // Add ourself to the Watchdog monitors.
1406        Watchdog.getInstance().addMonitor(this);
1407
1408        mProcessStatsThread = new Thread("ProcessStats") {
1409            public void run() {
1410                while (true) {
1411                    try {
1412                        try {
1413                            synchronized(this) {
1414                                final long now = SystemClock.uptimeMillis();
1415                                long nextCpuDelay = (mLastCpuTime+MONITOR_CPU_MAX_TIME)-now;
1416                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
1417                                //Log.i(TAG, "Cpu delay=" + nextCpuDelay
1418                                //        + ", write delay=" + nextWriteDelay);
1419                                if (nextWriteDelay < nextCpuDelay) {
1420                                    nextCpuDelay = nextWriteDelay;
1421                                }
1422                                if (nextCpuDelay > 0) {
1423                                    this.wait(nextCpuDelay);
1424                                }
1425                            }
1426                        } catch (InterruptedException e) {
1427                        }
1428
1429                        updateCpuStatsNow();
1430                    } catch (Exception e) {
1431                        Log.e(TAG, "Unexpected exception collecting process stats", e);
1432                    }
1433                }
1434            }
1435        };
1436        mProcessStatsThread.start();
1437    }
1438
1439    @Override
1440    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
1441            throws RemoteException {
1442        try {
1443            return super.onTransact(code, data, reply, flags);
1444        } catch (RuntimeException e) {
1445            // The activity manager only throws security exceptions, so let's
1446            // log all others.
1447            if (!(e instanceof SecurityException)) {
1448                Log.e(TAG, "Activity Manager Crash", e);
1449            }
1450            throw e;
1451        }
1452    }
1453
1454    void updateCpuStats() {
1455        synchronized (mProcessStatsThread) {
1456            final long now = SystemClock.uptimeMillis();
1457            if (mLastCpuTime < (now-MONITOR_CPU_MIN_TIME)) {
1458                mProcessStatsThread.notify();
1459            }
1460        }
1461    }
1462
1463    void updateCpuStatsNow() {
1464        synchronized (mProcessStatsThread) {
1465            final long now = SystemClock.uptimeMillis();
1466            boolean haveNewCpuStats = false;
1467
1468            if (MONITOR_CPU_USAGE &&
1469                    mLastCpuTime < (now-MONITOR_CPU_MIN_TIME)) {
1470                mLastCpuTime = now;
1471                haveNewCpuStats = true;
1472                mProcessStats.update();
1473                //Log.i(TAG, mProcessStats.printCurrentState());
1474                //Log.i(TAG, "Total CPU usage: "
1475                //        + mProcessStats.getTotalCpuPercent() + "%");
1476
1477                // Log the cpu usage if the property is set.
1478                if ("true".equals(SystemProperties.get("events.cpu"))) {
1479                    int user = mProcessStats.getLastUserTime();
1480                    int system = mProcessStats.getLastSystemTime();
1481                    int iowait = mProcessStats.getLastIoWaitTime();
1482                    int irq = mProcessStats.getLastIrqTime();
1483                    int softIrq = mProcessStats.getLastSoftIrqTime();
1484                    int idle = mProcessStats.getLastIdleTime();
1485
1486                    int total = user + system + iowait + irq + softIrq + idle;
1487                    if (total == 0) total = 1;
1488
1489                    EventLog.writeEvent(EventLogTags.CPU,
1490                            ((user+system+iowait+irq+softIrq) * 100) / total,
1491                            (user * 100) / total,
1492                            (system * 100) / total,
1493                            (iowait * 100) / total,
1494                            (irq * 100) / total,
1495                            (softIrq * 100) / total);
1496                }
1497            }
1498
1499            long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes();
1500            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
1501            synchronized(bstats) {
1502                synchronized(mPidsSelfLocked) {
1503                    if (haveNewCpuStats) {
1504                        if (mBatteryStatsService.isOnBattery()) {
1505                            final int N = mProcessStats.countWorkingStats();
1506                            for (int i=0; i<N; i++) {
1507                                ProcessStats.Stats st
1508                                        = mProcessStats.getWorkingStats(i);
1509                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
1510                                if (pr != null) {
1511                                    BatteryStatsImpl.Uid.Proc ps = pr.batteryStats;
1512                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
1513                                    ps.addSpeedStepTimes(cpuSpeedTimes);
1514                                } else {
1515                                    BatteryStatsImpl.Uid.Proc ps =
1516                                            bstats.getProcessStatsLocked(st.name, st.pid);
1517                                    if (ps != null) {
1518                                        ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
1519                                        ps.addSpeedStepTimes(cpuSpeedTimes);
1520                                    }
1521                                }
1522                            }
1523                        }
1524                    }
1525                }
1526
1527                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
1528                    mLastWriteTime = now;
1529                    mBatteryStatsService.getActiveStatistics().writeLocked();
1530                }
1531            }
1532        }
1533    }
1534
1535    /**
1536     * Initialize the application bind args. These are passed to each
1537     * process when the bindApplication() IPC is sent to the process. They're
1538     * lazily setup to make sure the services are running when they're asked for.
1539     */
1540    private HashMap<String, IBinder> getCommonServicesLocked() {
1541        if (mAppBindArgs == null) {
1542            mAppBindArgs = new HashMap<String, IBinder>();
1543
1544            // Setup the application init args
1545            mAppBindArgs.put("package", ServiceManager.getService("package"));
1546            mAppBindArgs.put("window", ServiceManager.getService("window"));
1547            mAppBindArgs.put(Context.ALARM_SERVICE,
1548                    ServiceManager.getService(Context.ALARM_SERVICE));
1549        }
1550        return mAppBindArgs;
1551    }
1552
1553    private final void setFocusedActivityLocked(HistoryRecord r) {
1554        if (mFocusedActivity != r) {
1555            mFocusedActivity = r;
1556            mWindowManager.setFocusedApp(r, true);
1557        }
1558    }
1559
1560    private final void updateLruProcessLocked(ProcessRecord app,
1561            boolean oomAdj, boolean updateActivityTime) {
1562        // put it on the LRU to keep track of when it should be exited.
1563        int lrui = mLruProcesses.indexOf(app);
1564        if (lrui >= 0) mLruProcesses.remove(lrui);
1565
1566        int i = mLruProcesses.size()-1;
1567        int skipTop = 0;
1568
1569        // compute the new weight for this process.
1570        if (updateActivityTime) {
1571            app.lastActivityTime = SystemClock.uptimeMillis();
1572        }
1573        if (app.activities.size() > 0) {
1574            // If this process has activities, we more strongly want to keep
1575            // it around.
1576            app.lruWeight = app.lastActivityTime;
1577        } else if (app.pubProviders.size() > 0) {
1578            // If this process contains content providers, we want to keep
1579            // it a little more strongly.
1580            app.lruWeight = app.lastActivityTime - CONTENT_APP_IDLE_OFFSET;
1581            // Also don't let it kick out the first few "real" hidden processes.
1582            skipTop = MIN_HIDDEN_APPS;
1583        } else {
1584            // If this process doesn't have activities, we less strongly
1585            // want to keep it around, and generally want to avoid getting
1586            // in front of any very recently used activities.
1587            app.lruWeight = app.lastActivityTime - EMPTY_APP_IDLE_OFFSET;
1588            // Also don't let it kick out the first few "real" hidden processes.
1589            skipTop = MIN_HIDDEN_APPS;
1590        }
1591        while (i >= 0) {
1592            ProcessRecord p = mLruProcesses.get(i);
1593            // If this app shouldn't be in front of the first N background
1594            // apps, then skip over that many that are currently hidden.
1595            if (skipTop > 0 && p.setAdj >= HIDDEN_APP_MIN_ADJ) {
1596                skipTop--;
1597            }
1598            if (p.lruWeight <= app.lruWeight){
1599                mLruProcesses.add(i+1, app);
1600                break;
1601            }
1602            i--;
1603        }
1604        if (i < 0) {
1605            mLruProcesses.add(0, app);
1606        }
1607
1608        //Log.i(TAG, "Putting proc to front: " + app.processName);
1609        if (oomAdj) {
1610            updateOomAdjLocked();
1611        }
1612    }
1613
1614    private final boolean updateLRUListLocked(HistoryRecord r) {
1615        final boolean hadit = mLRUActivities.remove(r);
1616        mLRUActivities.add(r);
1617        return hadit;
1618    }
1619
1620    private final HistoryRecord topRunningActivityLocked(HistoryRecord notTop) {
1621        int i = mHistory.size()-1;
1622        while (i >= 0) {
1623            HistoryRecord r = (HistoryRecord)mHistory.get(i);
1624            if (!r.finishing && r != notTop) {
1625                return r;
1626            }
1627            i--;
1628        }
1629        return null;
1630    }
1631
1632    private final HistoryRecord topRunningNonDelayedActivityLocked(HistoryRecord notTop) {
1633        int i = mHistory.size()-1;
1634        while (i >= 0) {
1635            HistoryRecord r = (HistoryRecord)mHistory.get(i);
1636            if (!r.finishing && !r.delayedResume && r != notTop) {
1637                return r;
1638            }
1639            i--;
1640        }
1641        return null;
1642    }
1643
1644    /**
1645     * This is a simplified version of topRunningActivityLocked that provides a number of
1646     * optional skip-over modes.  It is intended for use with the ActivityController hook only.
1647     *
1648     * @param token If non-null, any history records matching this token will be skipped.
1649     * @param taskId If non-zero, we'll attempt to skip over records with the same task ID.
1650     *
1651     * @return Returns the HistoryRecord of the next activity on the stack.
1652     */
1653    private final HistoryRecord topRunningActivityLocked(IBinder token, int taskId) {
1654        int i = mHistory.size()-1;
1655        while (i >= 0) {
1656            HistoryRecord r = (HistoryRecord)mHistory.get(i);
1657            // Note: the taskId check depends on real taskId fields being non-zero
1658            if (!r.finishing && (token != r) && (taskId != r.task.taskId)) {
1659                return r;
1660            }
1661            i--;
1662        }
1663        return null;
1664    }
1665
1666    private final ProcessRecord getProcessRecordLocked(
1667            String processName, int uid) {
1668        if (uid == Process.SYSTEM_UID) {
1669            // The system gets to run in any process.  If there are multiple
1670            // processes with the same uid, just pick the first (this
1671            // should never happen).
1672            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(
1673                    processName);
1674            return procs != null ? procs.valueAt(0) : null;
1675        }
1676        ProcessRecord proc = mProcessNames.get(processName, uid);
1677        return proc;
1678    }
1679
1680    private void ensurePackageDexOpt(String packageName) {
1681        IPackageManager pm = ActivityThread.getPackageManager();
1682        try {
1683            if (pm.performDexOpt(packageName)) {
1684                mDidDexOpt = true;
1685            }
1686        } catch (RemoteException e) {
1687        }
1688    }
1689
1690    private boolean isNextTransitionForward() {
1691        int transit = mWindowManager.getPendingAppTransition();
1692        return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
1693                || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
1694                || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT;
1695    }
1696
1697    private final boolean realStartActivityLocked(HistoryRecord r,
1698            ProcessRecord app, boolean andResume, boolean checkConfig)
1699            throws RemoteException {
1700
1701        r.startFreezingScreenLocked(app, 0);
1702        mWindowManager.setAppVisibility(r, true);
1703
1704        // Have the window manager re-evaluate the orientation of
1705        // the screen based on the new activity order.  Note that
1706        // as a result of this, it can call back into the activity
1707        // manager with a new orientation.  We don't care about that,
1708        // because the activity is not currently running so we are
1709        // just restarting it anyway.
1710        if (checkConfig) {
1711            Configuration config = mWindowManager.updateOrientationFromAppTokens(
1712                    mConfiguration,
1713                    r.mayFreezeScreenLocked(app) ? r : null);
1714            updateConfigurationLocked(config, r);
1715        }
1716
1717        r.app = app;
1718
1719        if (localLOGV) Log.v(TAG, "Launching: " + r);
1720
1721        int idx = app.activities.indexOf(r);
1722        if (idx < 0) {
1723            app.activities.add(r);
1724        }
1725        updateLruProcessLocked(app, true, true);
1726
1727        try {
1728            if (app.thread == null) {
1729                throw new RemoteException();
1730            }
1731            List<ResultInfo> results = null;
1732            List<Intent> newIntents = null;
1733            if (andResume) {
1734                results = r.results;
1735                newIntents = r.newIntents;
1736            }
1737            if (DEBUG_SWITCH) Log.v(TAG, "Launching: " + r
1738                    + " icicle=" + r.icicle
1739                    + " with results=" + results + " newIntents=" + newIntents
1740                    + " andResume=" + andResume);
1741            if (andResume) {
1742                EventLog.writeEvent(EventLogTags.AM_RESTART_ACTIVITY,
1743                        System.identityHashCode(r),
1744                        r.task.taskId, r.shortComponentName);
1745            }
1746            if (r.isHomeActivity) {
1747                mHomeProcess = app;
1748            }
1749            ensurePackageDexOpt(r.intent.getComponent().getPackageName());
1750            app.thread.scheduleLaunchActivity(new Intent(r.intent), r,
1751                    System.identityHashCode(r),
1752                    r.info, r.icicle, results, newIntents, !andResume,
1753                    isNextTransitionForward());
1754        } catch (RemoteException e) {
1755            if (r.launchFailed) {
1756                // This is the second time we failed -- finish activity
1757                // and give up.
1758                Log.e(TAG, "Second failure launching "
1759                      + r.intent.getComponent().flattenToShortString()
1760                      + ", giving up", e);
1761                appDiedLocked(app, app.pid, app.thread);
1762                requestFinishActivityLocked(r, Activity.RESULT_CANCELED, null,
1763                        "2nd-crash");
1764                return false;
1765            }
1766
1767            // This is the first time we failed -- restart process and
1768            // retry.
1769            app.activities.remove(r);
1770            throw e;
1771        }
1772
1773        r.launchFailed = false;
1774        if (updateLRUListLocked(r)) {
1775            Log.w(TAG, "Activity " + r
1776                  + " being launched, but already in LRU list");
1777        }
1778
1779        if (andResume) {
1780            // As part of the process of launching, ActivityThread also performs
1781            // a resume.
1782            r.state = ActivityState.RESUMED;
1783            r.icicle = null;
1784            r.haveState = false;
1785            r.stopped = false;
1786            mResumedActivity = r;
1787            r.task.touchActiveTime();
1788            completeResumeLocked(r);
1789            pauseIfSleepingLocked();
1790        } else {
1791            // This activity is not starting in the resumed state... which
1792            // should look like we asked it to pause+stop (but remain visible),
1793            // and it has done so and reported back the current icicle and
1794            // other state.
1795            r.state = ActivityState.STOPPED;
1796            r.stopped = true;
1797        }
1798
1799        // Launch the new version setup screen if needed.  We do this -after-
1800        // launching the initial activity (that is, home), so that it can have
1801        // a chance to initialize itself while in the background, making the
1802        // switch back to it faster and look better.
1803        startSetupActivityLocked();
1804
1805        return true;
1806    }
1807
1808    private final void startSpecificActivityLocked(HistoryRecord r,
1809            boolean andResume, boolean checkConfig) {
1810        // Is this activity's application already running?
1811        ProcessRecord app = getProcessRecordLocked(r.processName,
1812                r.info.applicationInfo.uid);
1813
1814        if (r.startTime == 0) {
1815            r.startTime = SystemClock.uptimeMillis();
1816            if (mInitialStartTime == 0) {
1817                mInitialStartTime = r.startTime;
1818            }
1819        } else if (mInitialStartTime == 0) {
1820            mInitialStartTime = SystemClock.uptimeMillis();
1821        }
1822
1823        if (app != null && app.thread != null) {
1824            try {
1825                realStartActivityLocked(r, app, andResume, checkConfig);
1826                return;
1827            } catch (RemoteException e) {
1828                Log.w(TAG, "Exception when starting activity "
1829                        + r.intent.getComponent().flattenToShortString(), e);
1830            }
1831
1832            // If a dead object exception was thrown -- fall through to
1833            // restart the application.
1834        }
1835
1836        startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
1837                "activity", r.intent.getComponent(), false);
1838    }
1839
1840    private final ProcessRecord startProcessLocked(String processName,
1841            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
1842            String hostingType, ComponentName hostingName, boolean allowWhileBooting) {
1843        ProcessRecord app = getProcessRecordLocked(processName, info.uid);
1844        // We don't have to do anything more if:
1845        // (1) There is an existing application record; and
1846        // (2) The caller doesn't think it is dead, OR there is no thread
1847        //     object attached to it so we know it couldn't have crashed; and
1848        // (3) There is a pid assigned to it, so it is either starting or
1849        //     already running.
1850        if (DEBUG_PROCESSES) Log.v(TAG, "startProcess: name=" + processName
1851                + " app=" + app + " knownToBeDead=" + knownToBeDead
1852                + " thread=" + (app != null ? app.thread : null)
1853                + " pid=" + (app != null ? app.pid : -1));
1854        if (app != null &&
1855                (!knownToBeDead || app.thread == null) && app.pid > 0) {
1856            return app;
1857        }
1858
1859        String hostingNameStr = hostingName != null
1860                ? hostingName.flattenToShortString() : null;
1861
1862        if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
1863            // If we are in the background, then check to see if this process
1864            // is bad.  If so, we will just silently fail.
1865            if (mBadProcesses.get(info.processName, info.uid) != null) {
1866                return null;
1867            }
1868        } else {
1869            // When the user is explicitly starting a process, then clear its
1870            // crash count so that we won't make it bad until they see at
1871            // least one crash dialog again, and make the process good again
1872            // if it had been bad.
1873            mProcessCrashTimes.remove(info.processName, info.uid);
1874            if (mBadProcesses.get(info.processName, info.uid) != null) {
1875                EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid,
1876                        info.processName);
1877                mBadProcesses.remove(info.processName, info.uid);
1878                if (app != null) {
1879                    app.bad = false;
1880                }
1881            }
1882        }
1883
1884        if (app == null) {
1885            app = newProcessRecordLocked(null, info, processName);
1886            mProcessNames.put(processName, info.uid, app);
1887        } else {
1888            // If this is a new package in the process, add the package to the list
1889            app.addPackage(info.packageName);
1890        }
1891
1892        // If the system is not ready yet, then hold off on starting this
1893        // process until it is.
1894        if (!mSystemReady
1895                && !isAllowedWhileBooting(info)
1896                && !allowWhileBooting) {
1897            if (!mProcessesOnHold.contains(app)) {
1898                mProcessesOnHold.add(app);
1899            }
1900            return app;
1901        }
1902
1903        startProcessLocked(app, hostingType, hostingNameStr);
1904        return (app.pid != 0) ? app : null;
1905    }
1906
1907    boolean isAllowedWhileBooting(ApplicationInfo ai) {
1908        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
1909    }
1910
1911    private final void startProcessLocked(ProcessRecord app,
1912            String hostingType, String hostingNameStr) {
1913        if (app.pid > 0 && app.pid != MY_PID) {
1914            synchronized (mPidsSelfLocked) {
1915                mPidsSelfLocked.remove(app.pid);
1916                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
1917            }
1918            app.pid = 0;
1919        }
1920
1921        mProcessesOnHold.remove(app);
1922
1923        updateCpuStats();
1924
1925        System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1);
1926        mProcDeaths[0] = 0;
1927
1928        try {
1929            int uid = app.info.uid;
1930            int[] gids = null;
1931            try {
1932                gids = mContext.getPackageManager().getPackageGids(
1933                        app.info.packageName);
1934            } catch (PackageManager.NameNotFoundException e) {
1935                Log.w(TAG, "Unable to retrieve gids", e);
1936            }
1937            if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
1938                if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
1939                        && mTopComponent != null
1940                        && app.processName.equals(mTopComponent.getPackageName())) {
1941                    uid = 0;
1942                }
1943                if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
1944                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
1945                    uid = 0;
1946                }
1947            }
1948            int debugFlags = 0;
1949            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
1950                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
1951            }
1952            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
1953                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
1954            }
1955            if ("1".equals(SystemProperties.get("debug.assert"))) {
1956                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
1957            }
1958            int pid = Process.start("android.app.ActivityThread",
1959                    mSimpleProcessManagement ? app.processName : null, uid, uid,
1960                    gids, debugFlags, null);
1961            BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
1962            synchronized (bs) {
1963                if (bs.isOnBattery()) {
1964                    app.batteryStats.incStartsLocked();
1965                }
1966            }
1967
1968            EventLog.writeEvent(EventLogTags.AM_PROC_START, pid, uid,
1969                    app.processName, hostingType,
1970                    hostingNameStr != null ? hostingNameStr : "");
1971
1972            if (app.persistent) {
1973                Watchdog.getInstance().processStarted(app, app.processName, pid);
1974            }
1975
1976            StringBuilder buf = mStringBuilder;
1977            buf.setLength(0);
1978            buf.append("Start proc ");
1979            buf.append(app.processName);
1980            buf.append(" for ");
1981            buf.append(hostingType);
1982            if (hostingNameStr != null) {
1983                buf.append(" ");
1984                buf.append(hostingNameStr);
1985            }
1986            buf.append(": pid=");
1987            buf.append(pid);
1988            buf.append(" uid=");
1989            buf.append(uid);
1990            buf.append(" gids={");
1991            if (gids != null) {
1992                for (int gi=0; gi<gids.length; gi++) {
1993                    if (gi != 0) buf.append(", ");
1994                    buf.append(gids[gi]);
1995
1996                }
1997            }
1998            buf.append("}");
1999            Log.i(TAG, buf.toString());
2000            if (pid == 0 || pid == MY_PID) {
2001                // Processes are being emulated with threads.
2002                app.pid = MY_PID;
2003                app.removed = false;
2004                mStartingProcesses.add(app);
2005            } else if (pid > 0) {
2006                app.pid = pid;
2007                app.removed = false;
2008                synchronized (mPidsSelfLocked) {
2009                    this.mPidsSelfLocked.put(pid, app);
2010                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2011                    msg.obj = app;
2012                    mHandler.sendMessageDelayed(msg, PROC_START_TIMEOUT);
2013                }
2014            } else {
2015                app.pid = 0;
2016                RuntimeException e = new RuntimeException(
2017                        "Failure starting process " + app.processName
2018                        + ": returned pid=" + pid);
2019                Log.e(TAG, e.getMessage(), e);
2020            }
2021        } catch (RuntimeException e) {
2022            // XXX do better error recovery.
2023            app.pid = 0;
2024            Log.e(TAG, "Failure starting process " + app.processName, e);
2025        }
2026    }
2027
2028    private final void startPausingLocked(boolean userLeaving, boolean uiSleeping) {
2029        if (mPausingActivity != null) {
2030            RuntimeException e = new RuntimeException();
2031            Log.e(TAG, "Trying to pause when pause is already pending for "
2032                  + mPausingActivity, e);
2033        }
2034        HistoryRecord prev = mResumedActivity;
2035        if (prev == null) {
2036            RuntimeException e = new RuntimeException();
2037            Log.e(TAG, "Trying to pause when nothing is resumed", e);
2038            resumeTopActivityLocked(null);
2039            return;
2040        }
2041        if (DEBUG_PAUSE) Log.v(TAG, "Start pausing: " + prev);
2042        mResumedActivity = null;
2043        mPausingActivity = prev;
2044        mLastPausedActivity = prev;
2045        prev.state = ActivityState.PAUSING;
2046        prev.task.touchActiveTime();
2047
2048        updateCpuStats();
2049
2050        if (prev.app != null && prev.app.thread != null) {
2051            if (DEBUG_PAUSE) Log.v(TAG, "Enqueueing pending pause: " + prev);
2052            try {
2053                EventLog.writeEvent(EventLogTags.AM_PAUSE_ACTIVITY,
2054                        System.identityHashCode(prev),
2055                        prev.shortComponentName);
2056                prev.app.thread.schedulePauseActivity(prev, prev.finishing, userLeaving,
2057                        prev.configChangeFlags);
2058                updateUsageStats(prev, false);
2059            } catch (Exception e) {
2060                // Ignore exception, if process died other code will cleanup.
2061                Log.w(TAG, "Exception thrown during pause", e);
2062                mPausingActivity = null;
2063                mLastPausedActivity = null;
2064            }
2065        } else {
2066            mPausingActivity = null;
2067            mLastPausedActivity = null;
2068        }
2069
2070        // If we are not going to sleep, we want to ensure the device is
2071        // awake until the next activity is started.
2072        if (!mSleeping && !mShuttingDown) {
2073            mLaunchingActivity.acquire();
2074            if (!mHandler.hasMessages(LAUNCH_TIMEOUT_MSG)) {
2075                // To be safe, don't allow the wake lock to be held for too long.
2076                Message msg = mHandler.obtainMessage(LAUNCH_TIMEOUT_MSG);
2077                mHandler.sendMessageDelayed(msg, LAUNCH_TIMEOUT);
2078            }
2079        }
2080
2081
2082        if (mPausingActivity != null) {
2083            // Have the window manager pause its key dispatching until the new
2084            // activity has started.  If we're pausing the activity just because
2085            // the screen is being turned off and the UI is sleeping, don't interrupt
2086            // key dispatch; the same activity will pick it up again on wakeup.
2087            if (!uiSleeping) {
2088                prev.pauseKeyDispatchingLocked();
2089            } else {
2090                if (DEBUG_PAUSE) Log.v(TAG, "Key dispatch not paused for screen off");
2091            }
2092
2093            // Schedule a pause timeout in case the app doesn't respond.
2094            // We don't give it much time because this directly impacts the
2095            // responsiveness seen by the user.
2096            Message msg = mHandler.obtainMessage(PAUSE_TIMEOUT_MSG);
2097            msg.obj = prev;
2098            mHandler.sendMessageDelayed(msg, PAUSE_TIMEOUT);
2099            if (DEBUG_PAUSE) Log.v(TAG, "Waiting for pause to complete...");
2100        } else {
2101            // This activity failed to schedule the
2102            // pause, so just treat it as being paused now.
2103            if (DEBUG_PAUSE) Log.v(TAG, "Activity not running, resuming next.");
2104            resumeTopActivityLocked(null);
2105        }
2106    }
2107
2108    private final void completePauseLocked() {
2109        HistoryRecord prev = mPausingActivity;
2110        if (DEBUG_PAUSE) Log.v(TAG, "Complete pause: " + prev);
2111
2112        if (prev != null) {
2113            if (prev.finishing) {
2114                if (DEBUG_PAUSE) Log.v(TAG, "Executing finish of activity: " + prev);
2115                prev = finishCurrentActivityLocked(prev, FINISH_AFTER_VISIBLE);
2116            } else if (prev.app != null) {
2117                if (DEBUG_PAUSE) Log.v(TAG, "Enqueueing pending stop: " + prev);
2118                if (prev.waitingVisible) {
2119                    prev.waitingVisible = false;
2120                    mWaitingVisibleActivities.remove(prev);
2121                    if (DEBUG_SWITCH || DEBUG_PAUSE) Log.v(
2122                            TAG, "Complete pause, no longer waiting: " + prev);
2123                }
2124                if (prev.configDestroy) {
2125                    // The previous is being paused because the configuration
2126                    // is changing, which means it is actually stopping...
2127                    // To juggle the fact that we are also starting a new
2128                    // instance right now, we need to first completely stop
2129                    // the current instance before starting the new one.
2130                    if (DEBUG_PAUSE) Log.v(TAG, "Destroying after pause: " + prev);
2131                    destroyActivityLocked(prev, true);
2132                } else {
2133                    mStoppingActivities.add(prev);
2134                    if (mStoppingActivities.size() > 3) {
2135                        // If we already have a few activities waiting to stop,
2136                        // then give up on things going idle and start clearing
2137                        // them out.
2138                        if (DEBUG_PAUSE) Log.v(TAG, "To many pending stops, forcing idle");
2139                        Message msg = Message.obtain();
2140                        msg.what = ActivityManagerService.IDLE_NOW_MSG;
2141                        mHandler.sendMessage(msg);
2142                    }
2143                }
2144            } else {
2145                if (DEBUG_PAUSE) Log.v(TAG, "App died during pause, not stopping: " + prev);
2146                prev = null;
2147            }
2148            mPausingActivity = null;
2149        }
2150
2151        if (!mSleeping && !mShuttingDown) {
2152            resumeTopActivityLocked(prev);
2153        } else {
2154            if (mGoingToSleep.isHeld()) {
2155                mGoingToSleep.release();
2156            }
2157            if (mShuttingDown) {
2158                notifyAll();
2159            }
2160        }
2161
2162        if (prev != null) {
2163            prev.resumeKeyDispatchingLocked();
2164        }
2165
2166        if (prev.app != null && prev.cpuTimeAtResume > 0 && mBatteryStatsService.isOnBattery()) {
2167            long diff = 0;
2168            synchronized (mProcessStatsThread) {
2169                diff = mProcessStats.getCpuTimeForPid(prev.app.pid) - prev.cpuTimeAtResume;
2170            }
2171            if (diff > 0) {
2172                BatteryStatsImpl bsi = mBatteryStatsService.getActiveStatistics();
2173                synchronized (bsi) {
2174                    BatteryStatsImpl.Uid.Proc ps =
2175                            bsi.getProcessStatsLocked(prev.info.applicationInfo.uid,
2176                            prev.info.packageName);
2177                    if (ps != null) {
2178                        ps.addForegroundTimeLocked(diff);
2179                    }
2180                }
2181            }
2182        }
2183        prev.cpuTimeAtResume = 0; // reset it
2184    }
2185
2186    /**
2187     * Once we know that we have asked an application to put an activity in
2188     * the resumed state (either by launching it or explicitly telling it),
2189     * this function updates the rest of our state to match that fact.
2190     */
2191    private final void completeResumeLocked(HistoryRecord next) {
2192        next.idle = false;
2193        next.results = null;
2194        next.newIntents = null;
2195
2196        // schedule an idle timeout in case the app doesn't do it for us.
2197        Message msg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG);
2198        msg.obj = next;
2199        mHandler.sendMessageDelayed(msg, IDLE_TIMEOUT);
2200
2201        if (false) {
2202            // The activity was never told to pause, so just keep
2203            // things going as-is.  To maintain our own state,
2204            // we need to emulate it coming back and saying it is
2205            // idle.
2206            msg = mHandler.obtainMessage(IDLE_NOW_MSG);
2207            msg.obj = next;
2208            mHandler.sendMessage(msg);
2209        }
2210
2211        reportResumedActivityLocked(next);
2212
2213        next.thumbnail = null;
2214        setFocusedActivityLocked(next);
2215        next.resumeKeyDispatchingLocked();
2216        ensureActivitiesVisibleLocked(null, 0);
2217        mWindowManager.executeAppTransition();
2218        mNoAnimActivities.clear();
2219
2220        // Mark the point when the activity is resuming
2221        // TODO: To be more accurate, the mark should be before the onCreate,
2222        //       not after the onResume. But for subsequent starts, onResume is fine.
2223        if (next.app != null) {
2224            synchronized (mProcessStatsThread) {
2225                next.cpuTimeAtResume = mProcessStats.getCpuTimeForPid(next.app.pid);
2226            }
2227        } else {
2228            next.cpuTimeAtResume = 0; // Couldn't get the cpu time of process
2229        }
2230    }
2231
2232    /**
2233     * Make sure that all activities that need to be visible (that is, they
2234     * currently can be seen by the user) actually are.
2235     */
2236    private final void ensureActivitiesVisibleLocked(HistoryRecord top,
2237            HistoryRecord starting, String onlyThisProcess, int configChanges) {
2238        if (DEBUG_VISBILITY) Log.v(
2239                TAG, "ensureActivitiesVisible behind " + top
2240                + " configChanges=0x" + Integer.toHexString(configChanges));
2241
2242        // If the top activity is not fullscreen, then we need to
2243        // make sure any activities under it are now visible.
2244        final int count = mHistory.size();
2245        int i = count-1;
2246        while (mHistory.get(i) != top) {
2247            i--;
2248        }
2249        HistoryRecord r;
2250        boolean behindFullscreen = false;
2251        for (; i>=0; i--) {
2252            r = (HistoryRecord)mHistory.get(i);
2253            if (DEBUG_VISBILITY) Log.v(
2254                    TAG, "Make visible? " + r + " finishing=" + r.finishing
2255                    + " state=" + r.state);
2256            if (r.finishing) {
2257                continue;
2258            }
2259
2260            final boolean doThisProcess = onlyThisProcess == null
2261                    || onlyThisProcess.equals(r.processName);
2262
2263            // First: if this is not the current activity being started, make
2264            // sure it matches the current configuration.
2265            if (r != starting && doThisProcess) {
2266                ensureActivityConfigurationLocked(r, 0);
2267            }
2268
2269            if (r.app == null || r.app.thread == null) {
2270                if (onlyThisProcess == null
2271                        || onlyThisProcess.equals(r.processName)) {
2272                    // This activity needs to be visible, but isn't even
2273                    // running...  get it started, but don't resume it
2274                    // at this point.
2275                    if (DEBUG_VISBILITY) Log.v(
2276                            TAG, "Start and freeze screen for " + r);
2277                    if (r != starting) {
2278                        r.startFreezingScreenLocked(r.app, configChanges);
2279                    }
2280                    if (!r.visible) {
2281                        if (DEBUG_VISBILITY) Log.v(
2282                                TAG, "Starting and making visible: " + r);
2283                        mWindowManager.setAppVisibility(r, true);
2284                    }
2285                    if (r != starting) {
2286                        startSpecificActivityLocked(r, false, false);
2287                    }
2288                }
2289
2290            } else if (r.visible) {
2291                // If this activity is already visible, then there is nothing
2292                // else to do here.
2293                if (DEBUG_VISBILITY) Log.v(
2294                        TAG, "Skipping: already visible at " + r);
2295                r.stopFreezingScreenLocked(false);
2296
2297            } else if (onlyThisProcess == null) {
2298                // This activity is not currently visible, but is running.
2299                // Tell it to become visible.
2300                r.visible = true;
2301                if (r.state != ActivityState.RESUMED && r != starting) {
2302                    // If this activity is paused, tell it
2303                    // to now show its window.
2304                    if (DEBUG_VISBILITY) Log.v(
2305                            TAG, "Making visible and scheduling visibility: " + r);
2306                    try {
2307                        mWindowManager.setAppVisibility(r, true);
2308                        r.app.thread.scheduleWindowVisibility(r, true);
2309                        r.stopFreezingScreenLocked(false);
2310                    } catch (Exception e) {
2311                        // Just skip on any failure; we'll make it
2312                        // visible when it next restarts.
2313                        Log.w(TAG, "Exception thrown making visibile: "
2314                                + r.intent.getComponent(), e);
2315                    }
2316                }
2317            }
2318
2319            // Aggregate current change flags.
2320            configChanges |= r.configChangeFlags;
2321
2322            if (r.fullscreen) {
2323                // At this point, nothing else needs to be shown
2324                if (DEBUG_VISBILITY) Log.v(
2325                        TAG, "Stopping: fullscreen at " + r);
2326                behindFullscreen = true;
2327                i--;
2328                break;
2329            }
2330        }
2331
2332        // Now for any activities that aren't visible to the user, make
2333        // sure they no longer are keeping the screen frozen.
2334        while (i >= 0) {
2335            r = (HistoryRecord)mHistory.get(i);
2336            if (DEBUG_VISBILITY) Log.v(
2337                    TAG, "Make invisible? " + r + " finishing=" + r.finishing
2338                    + " state=" + r.state
2339                    + " behindFullscreen=" + behindFullscreen);
2340            if (!r.finishing) {
2341                if (behindFullscreen) {
2342                    if (r.visible) {
2343                        if (DEBUG_VISBILITY) Log.v(
2344                                TAG, "Making invisible: " + r);
2345                        r.visible = false;
2346                        try {
2347                            mWindowManager.setAppVisibility(r, false);
2348                            if ((r.state == ActivityState.STOPPING
2349                                    || r.state == ActivityState.STOPPED)
2350                                    && r.app != null && r.app.thread != null) {
2351                                if (DEBUG_VISBILITY) Log.v(
2352                                        TAG, "Scheduling invisibility: " + r);
2353                                r.app.thread.scheduleWindowVisibility(r, false);
2354                            }
2355                        } catch (Exception e) {
2356                            // Just skip on any failure; we'll make it
2357                            // visible when it next restarts.
2358                            Log.w(TAG, "Exception thrown making hidden: "
2359                                    + r.intent.getComponent(), e);
2360                        }
2361                    } else {
2362                        if (DEBUG_VISBILITY) Log.v(
2363                                TAG, "Already invisible: " + r);
2364                    }
2365                } else if (r.fullscreen) {
2366                    if (DEBUG_VISBILITY) Log.v(
2367                            TAG, "Now behindFullscreen: " + r);
2368                    behindFullscreen = true;
2369                }
2370            }
2371            i--;
2372        }
2373    }
2374
2375    /**
2376     * Version of ensureActivitiesVisible that can easily be called anywhere.
2377     */
2378    private final void ensureActivitiesVisibleLocked(HistoryRecord starting,
2379            int configChanges) {
2380        HistoryRecord r = topRunningActivityLocked(null);
2381        if (r != null) {
2382            ensureActivitiesVisibleLocked(r, starting, null, configChanges);
2383        }
2384    }
2385
2386    private void updateUsageStats(HistoryRecord resumedComponent, boolean resumed) {
2387        if (resumed) {
2388            mUsageStatsService.noteResumeComponent(resumedComponent.realActivity);
2389        } else {
2390            mUsageStatsService.notePauseComponent(resumedComponent.realActivity);
2391        }
2392    }
2393
2394    private boolean startHomeActivityLocked() {
2395        if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2396                && mTopAction == null) {
2397            // We are running in factory test mode, but unable to find
2398            // the factory test app, so just sit around displaying the
2399            // error message and don't try to start anything.
2400            return false;
2401        }
2402        Intent intent = new Intent(
2403            mTopAction,
2404            mTopData != null ? Uri.parse(mTopData) : null);
2405        intent.setComponent(mTopComponent);
2406        if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
2407            intent.addCategory(Intent.CATEGORY_HOME);
2408        }
2409        ActivityInfo aInfo =
2410            intent.resolveActivityInfo(mContext.getPackageManager(),
2411                    STOCK_PM_FLAGS);
2412        if (aInfo != null) {
2413            intent.setComponent(new ComponentName(
2414                    aInfo.applicationInfo.packageName, aInfo.name));
2415            // Don't do this if the home app is currently being
2416            // instrumented.
2417            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2418                    aInfo.applicationInfo.uid);
2419            if (app == null || app.instrumentationClass == null) {
2420                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
2421                startActivityLocked(null, intent, null, null, 0, aInfo,
2422                        null, null, 0, 0, 0, false, false);
2423            }
2424        }
2425
2426
2427        return true;
2428    }
2429
2430    /**
2431     * Starts the "new version setup screen" if appropriate.
2432     */
2433    private void startSetupActivityLocked() {
2434        // Only do this once per boot.
2435        if (mCheckedForSetup) {
2436            return;
2437        }
2438
2439        // We will show this screen if the current one is a different
2440        // version than the last one shown, and we are not running in
2441        // low-level factory test mode.
2442        final ContentResolver resolver = mContext.getContentResolver();
2443        if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL &&
2444                Settings.Secure.getInt(resolver,
2445                        Settings.Secure.DEVICE_PROVISIONED, 0) != 0) {
2446            mCheckedForSetup = true;
2447
2448            // See if we should be showing the platform update setup UI.
2449            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
2450            List<ResolveInfo> ris = mSelf.mContext.getPackageManager()
2451                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
2452
2453            // We don't allow third party apps to replace this.
2454            ResolveInfo ri = null;
2455            for (int i=0; ris != null && i<ris.size(); i++) {
2456                if ((ris.get(i).activityInfo.applicationInfo.flags
2457                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
2458                    ri = ris.get(i);
2459                    break;
2460                }
2461            }
2462
2463            if (ri != null) {
2464                String vers = ri.activityInfo.metaData != null
2465                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2466                        : null;
2467                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2468                    vers = ri.activityInfo.applicationInfo.metaData.getString(
2469                            Intent.METADATA_SETUP_VERSION);
2470                }
2471                String lastVers = Settings.Secure.getString(
2472                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
2473                if (vers != null && !vers.equals(lastVers)) {
2474                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2475                    intent.setComponent(new ComponentName(
2476                            ri.activityInfo.packageName, ri.activityInfo.name));
2477                    startActivityLocked(null, intent, null, null, 0, ri.activityInfo,
2478                            null, null, 0, 0, 0, false, false);
2479                }
2480            }
2481        }
2482    }
2483
2484    private void reportResumedActivityLocked(HistoryRecord r) {
2485        //Log.i(TAG, "**** REPORT RESUME: " + r);
2486
2487        final int identHash = System.identityHashCode(r);
2488        updateUsageStats(r, true);
2489
2490        int i = mWatchers.beginBroadcast();
2491        while (i > 0) {
2492            i--;
2493            IActivityWatcher w = mWatchers.getBroadcastItem(i);
2494            if (w != null) {
2495                try {
2496                    w.activityResuming(identHash);
2497                } catch (RemoteException e) {
2498                }
2499            }
2500        }
2501        mWatchers.finishBroadcast();
2502    }
2503
2504    /**
2505     * Ensure that the top activity in the stack is resumed.
2506     *
2507     * @param prev The previously resumed activity, for when in the process
2508     * of pausing; can be null to call from elsewhere.
2509     *
2510     * @return Returns true if something is being resumed, or false if
2511     * nothing happened.
2512     */
2513    private final boolean resumeTopActivityLocked(HistoryRecord prev) {
2514        // Find the first activity that is not finishing.
2515        HistoryRecord next = topRunningActivityLocked(null);
2516
2517        // Remember how we'll process this pause/resume situation, and ensure
2518        // that the state is reset however we wind up proceeding.
2519        final boolean userLeaving = mUserLeaving;
2520        mUserLeaving = false;
2521
2522        if (next == null) {
2523            // There are no more activities!  Let's just start up the
2524            // Launcher...
2525            return startHomeActivityLocked();
2526        }
2527
2528        next.delayedResume = false;
2529
2530        // If the top activity is the resumed one, nothing to do.
2531        if (mResumedActivity == next && next.state == ActivityState.RESUMED) {
2532            // Make sure we have executed any pending transitions, since there
2533            // should be nothing left to do at this point.
2534            mWindowManager.executeAppTransition();
2535            mNoAnimActivities.clear();
2536            return false;
2537        }
2538
2539        // If we are sleeping, and there is no resumed activity, and the top
2540        // activity is paused, well that is the state we want.
2541        if ((mSleeping || mShuttingDown)
2542                && mLastPausedActivity == next && next.state == ActivityState.PAUSED) {
2543            // Make sure we have executed any pending transitions, since there
2544            // should be nothing left to do at this point.
2545            mWindowManager.executeAppTransition();
2546            mNoAnimActivities.clear();
2547            return false;
2548        }
2549
2550        // The activity may be waiting for stop, but that is no longer
2551        // appropriate for it.
2552        mStoppingActivities.remove(next);
2553        mWaitingVisibleActivities.remove(next);
2554
2555        if (DEBUG_SWITCH) Log.v(TAG, "Resuming " + next);
2556
2557        // If we are currently pausing an activity, then don't do anything
2558        // until that is done.
2559        if (mPausingActivity != null) {
2560            if (DEBUG_SWITCH) Log.v(TAG, "Skip resume: pausing=" + mPausingActivity);
2561            return false;
2562        }
2563
2564        // We need to start pausing the current activity so the top one
2565        // can be resumed...
2566        if (mResumedActivity != null) {
2567            if (DEBUG_SWITCH) Log.v(TAG, "Skip resume: need to start pausing");
2568            startPausingLocked(userLeaving, false);
2569            return true;
2570        }
2571
2572        if (prev != null && prev != next) {
2573            if (!prev.waitingVisible && next != null && !next.nowVisible) {
2574                prev.waitingVisible = true;
2575                mWaitingVisibleActivities.add(prev);
2576                if (DEBUG_SWITCH) Log.v(
2577                        TAG, "Resuming top, waiting visible to hide: " + prev);
2578            } else {
2579                // The next activity is already visible, so hide the previous
2580                // activity's windows right now so we can show the new one ASAP.
2581                // We only do this if the previous is finishing, which should mean
2582                // it is on top of the one being resumed so hiding it quickly
2583                // is good.  Otherwise, we want to do the normal route of allowing
2584                // the resumed activity to be shown so we can decide if the
2585                // previous should actually be hidden depending on whether the
2586                // new one is found to be full-screen or not.
2587                if (prev.finishing) {
2588                    mWindowManager.setAppVisibility(prev, false);
2589                    if (DEBUG_SWITCH) Log.v(TAG, "Not waiting for visible to hide: "
2590                            + prev + ", waitingVisible="
2591                            + (prev != null ? prev.waitingVisible : null)
2592                            + ", nowVisible=" + next.nowVisible);
2593                } else {
2594                    if (DEBUG_SWITCH) Log.v(TAG, "Previous already visible but still waiting to hide: "
2595                        + prev + ", waitingVisible="
2596                        + (prev != null ? prev.waitingVisible : null)
2597                        + ", nowVisible=" + next.nowVisible);
2598                }
2599            }
2600        }
2601
2602        // We are starting up the next activity, so tell the window manager
2603        // that the previous one will be hidden soon.  This way it can know
2604        // to ignore it when computing the desired screen orientation.
2605        if (prev != null) {
2606            if (prev.finishing) {
2607                if (DEBUG_TRANSITION) Log.v(TAG,
2608                        "Prepare close transition: prev=" + prev);
2609                if (mNoAnimActivities.contains(prev)) {
2610                    mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_NONE);
2611                } else {
2612                    mWindowManager.prepareAppTransition(prev.task == next.task
2613                            ? WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE
2614                            : WindowManagerPolicy.TRANSIT_TASK_CLOSE);
2615                }
2616                mWindowManager.setAppWillBeHidden(prev);
2617                mWindowManager.setAppVisibility(prev, false);
2618            } else {
2619                if (DEBUG_TRANSITION) Log.v(TAG,
2620                        "Prepare open transition: prev=" + prev);
2621                if (mNoAnimActivities.contains(next)) {
2622                    mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_NONE);
2623                } else {
2624                    mWindowManager.prepareAppTransition(prev.task == next.task
2625                            ? WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
2626                            : WindowManagerPolicy.TRANSIT_TASK_OPEN);
2627                }
2628            }
2629            if (false) {
2630                mWindowManager.setAppWillBeHidden(prev);
2631                mWindowManager.setAppVisibility(prev, false);
2632            }
2633        } else if (mHistory.size() > 1) {
2634            if (DEBUG_TRANSITION) Log.v(TAG,
2635                    "Prepare open transition: no previous");
2636            if (mNoAnimActivities.contains(next)) {
2637                mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_NONE);
2638            } else {
2639                mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN);
2640            }
2641        }
2642
2643        if (next.app != null && next.app.thread != null) {
2644            if (DEBUG_SWITCH) Log.v(TAG, "Resume running: " + next);
2645
2646            // This activity is now becoming visible.
2647            mWindowManager.setAppVisibility(next, true);
2648
2649            HistoryRecord lastResumedActivity = mResumedActivity;
2650            ActivityState lastState = next.state;
2651
2652            updateCpuStats();
2653
2654            next.state = ActivityState.RESUMED;
2655            mResumedActivity = next;
2656            next.task.touchActiveTime();
2657            updateLruProcessLocked(next.app, true, true);
2658            updateLRUListLocked(next);
2659
2660            // Have the window manager re-evaluate the orientation of
2661            // the screen based on the new activity order.
2662            boolean updated;
2663            synchronized (this) {
2664                Configuration config = mWindowManager.updateOrientationFromAppTokens(
2665                        mConfiguration,
2666                        next.mayFreezeScreenLocked(next.app) ? next : null);
2667                if (config != null) {
2668                    /*
2669                     * Explicitly restore the locale to the one from the
2670                     * old configuration, since the one that comes back from
2671                     * the window manager has the default (boot) locale.
2672                     *
2673                     * It looks like previously the locale picker only worked
2674                     * by coincidence: usually it would do its setting of
2675                     * the locale after the activity transition, so it didn't
2676                     * matter that this lost it.  With the synchronized
2677                     * block now keeping them from happening at the same time,
2678                     * this one always would happen second and undo what the
2679                     * locale picker had just done.
2680                     */
2681                    config.locale = mConfiguration.locale;
2682                    next.frozenBeforeDestroy = true;
2683                }
2684                updated = updateConfigurationLocked(config, next);
2685            }
2686            if (!updated) {
2687                // The configuration update wasn't able to keep the existing
2688                // instance of the activity, and instead started a new one.
2689                // We should be all done, but let's just make sure our activity
2690                // is still at the top and schedule another run if something
2691                // weird happened.
2692                HistoryRecord nextNext = topRunningActivityLocked(null);
2693                if (DEBUG_SWITCH) Log.i(TAG,
2694                        "Activity config changed during resume: " + next
2695                        + ", new next: " + nextNext);
2696                if (nextNext != next) {
2697                    // Do over!
2698                    mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG);
2699                }
2700                setFocusedActivityLocked(next);
2701                ensureActivitiesVisibleLocked(null, 0);
2702                mWindowManager.executeAppTransition();
2703                mNoAnimActivities.clear();
2704                return true;
2705            }
2706
2707            try {
2708                // Deliver all pending results.
2709                ArrayList a = next.results;
2710                if (a != null) {
2711                    final int N = a.size();
2712                    if (!next.finishing && N > 0) {
2713                        if (DEBUG_RESULTS) Log.v(
2714                                TAG, "Delivering results to " + next
2715                                + ": " + a);
2716                        next.app.thread.scheduleSendResult(next, a);
2717                    }
2718                }
2719
2720                if (next.newIntents != null) {
2721                    next.app.thread.scheduleNewIntent(next.newIntents, next);
2722                }
2723
2724                EventLog.writeEvent(EventLogTags.AM_RESUME_ACTIVITY,
2725                        System.identityHashCode(next),
2726                        next.task.taskId, next.shortComponentName);
2727
2728                next.app.thread.scheduleResumeActivity(next,
2729                        isNextTransitionForward());
2730
2731                pauseIfSleepingLocked();
2732
2733            } catch (Exception e) {
2734                // Whoops, need to restart this activity!
2735                next.state = lastState;
2736                mResumedActivity = lastResumedActivity;
2737                Log.i(TAG, "Restarting because process died: " + next);
2738                if (!next.hasBeenLaunched) {
2739                    next.hasBeenLaunched = true;
2740                } else {
2741                    if (SHOW_APP_STARTING_ICON) {
2742                        mWindowManager.setAppStartingWindow(
2743                                next, next.packageName, next.theme,
2744                                next.nonLocalizedLabel,
2745                                next.labelRes, next.icon, null, true);
2746                    }
2747                }
2748                startSpecificActivityLocked(next, true, false);
2749                return true;
2750            }
2751
2752            // From this point on, if something goes wrong there is no way
2753            // to recover the activity.
2754            try {
2755                next.visible = true;
2756                completeResumeLocked(next);
2757            } catch (Exception e) {
2758                // If any exception gets thrown, toss away this
2759                // activity and try the next one.
2760                Log.w(TAG, "Exception thrown during resume of " + next, e);
2761                requestFinishActivityLocked(next, Activity.RESULT_CANCELED, null,
2762                        "resume-exception");
2763                return true;
2764            }
2765
2766            // Didn't need to use the icicle, and it is now out of date.
2767            next.icicle = null;
2768            next.haveState = false;
2769            next.stopped = false;
2770
2771        } else {
2772            // Whoops, need to restart this activity!
2773            if (!next.hasBeenLaunched) {
2774                next.hasBeenLaunched = true;
2775            } else {
2776                if (SHOW_APP_STARTING_ICON) {
2777                    mWindowManager.setAppStartingWindow(
2778                            next, next.packageName, next.theme,
2779                            next.nonLocalizedLabel,
2780                            next.labelRes, next.icon, null, true);
2781                }
2782                if (DEBUG_SWITCH) Log.v(TAG, "Restarting: " + next);
2783            }
2784            startSpecificActivityLocked(next, true, true);
2785        }
2786
2787        return true;
2788    }
2789
2790    private final void startActivityLocked(HistoryRecord r, boolean newTask,
2791            boolean doResume) {
2792        final int NH = mHistory.size();
2793
2794        int addPos = -1;
2795
2796        if (!newTask) {
2797            // If starting in an existing task, find where that is...
2798            HistoryRecord next = null;
2799            boolean startIt = true;
2800            for (int i = NH-1; i >= 0; i--) {
2801                HistoryRecord p = (HistoryRecord)mHistory.get(i);
2802                if (p.finishing) {
2803                    continue;
2804                }
2805                if (p.task == r.task) {
2806                    // Here it is!  Now, if this is not yet visible to the
2807                    // user, then just add it without starting; it will
2808                    // get started when the user navigates back to it.
2809                    addPos = i+1;
2810                    if (!startIt) {
2811                        mHistory.add(addPos, r);
2812                        r.inHistory = true;
2813                        r.task.numActivities++;
2814                        mWindowManager.addAppToken(addPos, r, r.task.taskId,
2815                                r.info.screenOrientation, r.fullscreen);
2816                        if (VALIDATE_TOKENS) {
2817                            mWindowManager.validateAppTokens(mHistory);
2818                        }
2819                        return;
2820                    }
2821                    break;
2822                }
2823                if (p.fullscreen) {
2824                    startIt = false;
2825                }
2826                next = p;
2827            }
2828        }
2829
2830        // Place a new activity at top of stack, so it is next to interact
2831        // with the user.
2832        if (addPos < 0) {
2833            addPos = mHistory.size();
2834        }
2835
2836        // If we are not placing the new activity frontmost, we do not want
2837        // to deliver the onUserLeaving callback to the actual frontmost
2838        // activity
2839        if (addPos < NH) {
2840            mUserLeaving = false;
2841            if (DEBUG_USER_LEAVING) Log.v(TAG, "startActivity() behind front, mUserLeaving=false");
2842        }
2843
2844        // Slot the activity into the history stack and proceed
2845        mHistory.add(addPos, r);
2846        r.inHistory = true;
2847        r.frontOfTask = newTask;
2848        r.task.numActivities++;
2849        if (NH > 0) {
2850            // We want to show the starting preview window if we are
2851            // switching to a new task, or the next activity's process is
2852            // not currently running.
2853            boolean showStartingIcon = newTask;
2854            ProcessRecord proc = r.app;
2855            if (proc == null) {
2856                proc = mProcessNames.get(r.processName, r.info.applicationInfo.uid);
2857            }
2858            if (proc == null || proc.thread == null) {
2859                showStartingIcon = true;
2860            }
2861            if (DEBUG_TRANSITION) Log.v(TAG,
2862                    "Prepare open transition: starting " + r);
2863            if ((r.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) {
2864                mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_NONE);
2865                mNoAnimActivities.add(r);
2866            } else if ((r.intent.getFlags()&Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0) {
2867                mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_TASK_OPEN);
2868                mNoAnimActivities.remove(r);
2869            } else {
2870                mWindowManager.prepareAppTransition(newTask
2871                        ? WindowManagerPolicy.TRANSIT_TASK_OPEN
2872                        : WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN);
2873                mNoAnimActivities.remove(r);
2874            }
2875            mWindowManager.addAppToken(
2876                    addPos, r, r.task.taskId, r.info.screenOrientation, r.fullscreen);
2877            boolean doShow = true;
2878            if (newTask) {
2879                // Even though this activity is starting fresh, we still need
2880                // to reset it to make sure we apply affinities to move any
2881                // existing activities from other tasks in to it.
2882                // If the caller has requested that the target task be
2883                // reset, then do so.
2884                if ((r.intent.getFlags()
2885                        &Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
2886                    resetTaskIfNeededLocked(r, r);
2887                    doShow = topRunningNonDelayedActivityLocked(null) == r;
2888                }
2889            }
2890            if (SHOW_APP_STARTING_ICON && doShow) {
2891                // Figure out if we are transitioning from another activity that is
2892                // "has the same starting icon" as the next one.  This allows the
2893                // window manager to keep the previous window it had previously
2894                // created, if it still had one.
2895                HistoryRecord prev = mResumedActivity;
2896                if (prev != null) {
2897                    // We don't want to reuse the previous starting preview if:
2898                    // (1) The current activity is in a different task.
2899                    if (prev.task != r.task) prev = null;
2900                    // (2) The current activity is already displayed.
2901                    else if (prev.nowVisible) prev = null;
2902                }
2903                mWindowManager.setAppStartingWindow(
2904                        r, r.packageName, r.theme, r.nonLocalizedLabel,
2905                        r.labelRes, r.icon, prev, showStartingIcon);
2906            }
2907        } else {
2908            // If this is the first activity, don't do any fancy animations,
2909            // because there is nothing for it to animate on top of.
2910            mWindowManager.addAppToken(addPos, r, r.task.taskId,
2911                    r.info.screenOrientation, r.fullscreen);
2912        }
2913        if (VALIDATE_TOKENS) {
2914            mWindowManager.validateAppTokens(mHistory);
2915        }
2916
2917        if (doResume) {
2918            resumeTopActivityLocked(null);
2919        }
2920    }
2921
2922    /**
2923     * Perform clear operation as requested by
2924     * {@link Intent#FLAG_ACTIVITY_CLEAR_TOP}: search from the top of the
2925     * stack to the given task, then look for
2926     * an instance of that activity in the stack and, if found, finish all
2927     * activities on top of it and return the instance.
2928     *
2929     * @param newR Description of the new activity being started.
2930     * @return Returns the old activity that should be continue to be used,
2931     * or null if none was found.
2932     */
2933    private final HistoryRecord performClearTaskLocked(int taskId,
2934            HistoryRecord newR, int launchFlags, boolean doClear) {
2935        int i = mHistory.size();
2936
2937        // First find the requested task.
2938        while (i > 0) {
2939            i--;
2940            HistoryRecord r = (HistoryRecord)mHistory.get(i);
2941            if (r.task.taskId == taskId) {
2942                i++;
2943                break;
2944            }
2945        }
2946
2947        // Now clear it.
2948        while (i > 0) {
2949            i--;
2950            HistoryRecord r = (HistoryRecord)mHistory.get(i);
2951            if (r.finishing) {
2952                continue;
2953            }
2954            if (r.task.taskId != taskId) {
2955                return null;
2956            }
2957            if (r.realActivity.equals(newR.realActivity)) {
2958                // Here it is!  Now finish everything in front...
2959                HistoryRecord ret = r;
2960                if (doClear) {
2961                    while (i < (mHistory.size()-1)) {
2962                        i++;
2963                        r = (HistoryRecord)mHistory.get(i);
2964                        if (r.finishing) {
2965                            continue;
2966                        }
2967                        if (finishActivityLocked(r, i, Activity.RESULT_CANCELED,
2968                                null, "clear")) {
2969                            i--;
2970                        }
2971                    }
2972                }
2973
2974                // Finally, if this is a normal launch mode (that is, not
2975                // expecting onNewIntent()), then we will finish the current
2976                // instance of the activity so a new fresh one can be started.
2977                if (ret.launchMode == ActivityInfo.LAUNCH_MULTIPLE
2978                        && (launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) == 0) {
2979                    if (!ret.finishing) {
2980                        int index = indexOfTokenLocked(ret);
2981                        if (index >= 0) {
2982                            finishActivityLocked(ret, 0, Activity.RESULT_CANCELED,
2983                                    null, "clear");
2984                        }
2985                        return null;
2986                    }
2987                }
2988
2989                return ret;
2990            }
2991        }
2992
2993        return null;
2994    }
2995
2996    /**
2997     * Find the activity in the history stack within the given task.  Returns
2998     * the index within the history at which it's found, or < 0 if not found.
2999     */
3000    private final int findActivityInHistoryLocked(HistoryRecord r, int task) {
3001        int i = mHistory.size();
3002        while (i > 0) {
3003            i--;
3004            HistoryRecord candidate = (HistoryRecord)mHistory.get(i);
3005            if (candidate.task.taskId != task) {
3006                break;
3007            }
3008            if (candidate.realActivity.equals(r.realActivity)) {
3009                return i;
3010            }
3011        }
3012
3013        return -1;
3014    }
3015
3016    /**
3017     * Reorder the history stack so that the activity at the given index is
3018     * brought to the front.
3019     */
3020    private final HistoryRecord moveActivityToFrontLocked(int where) {
3021        HistoryRecord newTop = (HistoryRecord)mHistory.remove(where);
3022        int top = mHistory.size();
3023        HistoryRecord oldTop = (HistoryRecord)mHistory.get(top-1);
3024        mHistory.add(top, newTop);
3025        oldTop.frontOfTask = false;
3026        newTop.frontOfTask = true;
3027        return newTop;
3028    }
3029
3030    /**
3031     * Deliver a new Intent to an existing activity, so that its onNewIntent()
3032     * method will be called at the proper time.
3033     */
3034    private final void deliverNewIntentLocked(HistoryRecord r, Intent intent) {
3035        boolean sent = false;
3036        if (r.state == ActivityState.RESUMED
3037                && r.app != null && r.app.thread != null) {
3038            try {
3039                ArrayList<Intent> ar = new ArrayList<Intent>();
3040                ar.add(new Intent(intent));
3041                r.app.thread.scheduleNewIntent(ar, r);
3042                sent = true;
3043            } catch (Exception e) {
3044                Log.w(TAG, "Exception thrown sending new intent to " + r, e);
3045            }
3046        }
3047        if (!sent) {
3048            r.addNewIntentLocked(new Intent(intent));
3049        }
3050    }
3051
3052    private final void logStartActivity(int tag, HistoryRecord r,
3053            TaskRecord task) {
3054        EventLog.writeEvent(tag,
3055                System.identityHashCode(r), task.taskId,
3056                r.shortComponentName, r.intent.getAction(),
3057                r.intent.getType(), r.intent.getDataString(),
3058                r.intent.getFlags());
3059    }
3060
3061    private final int startActivityLocked(IApplicationThread caller,
3062            Intent intent, String resolvedType,
3063            Uri[] grantedUriPermissions,
3064            int grantedMode, ActivityInfo aInfo, IBinder resultTo,
3065            String resultWho, int requestCode,
3066            int callingPid, int callingUid, boolean onlyIfNeeded,
3067            boolean componentSpecified) {
3068        Log.i(TAG, "Starting activity: " + intent);
3069
3070        HistoryRecord sourceRecord = null;
3071        HistoryRecord resultRecord = null;
3072        if (resultTo != null) {
3073            int index = indexOfTokenLocked(resultTo);
3074            if (DEBUG_RESULTS) Log.v(
3075                TAG, "Sending result to " + resultTo + " (index " + index + ")");
3076            if (index >= 0) {
3077                sourceRecord = (HistoryRecord)mHistory.get(index);
3078                if (requestCode >= 0 && !sourceRecord.finishing) {
3079                    resultRecord = sourceRecord;
3080                }
3081            }
3082        }
3083
3084        int launchFlags = intent.getFlags();
3085
3086        if ((launchFlags&Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0
3087                && sourceRecord != null) {
3088            // Transfer the result target from the source activity to the new
3089            // one being started, including any failures.
3090            if (requestCode >= 0) {
3091                return START_FORWARD_AND_REQUEST_CONFLICT;
3092            }
3093            resultRecord = sourceRecord.resultTo;
3094            resultWho = sourceRecord.resultWho;
3095            requestCode = sourceRecord.requestCode;
3096            sourceRecord.resultTo = null;
3097            if (resultRecord != null) {
3098                resultRecord.removeResultsLocked(
3099                    sourceRecord, resultWho, requestCode);
3100            }
3101        }
3102
3103        int err = START_SUCCESS;
3104
3105        if (intent.getComponent() == null) {
3106            // We couldn't find a class that can handle the given Intent.
3107            // That's the end of that!
3108            err = START_INTENT_NOT_RESOLVED;
3109        }
3110
3111        if (err == START_SUCCESS && aInfo == null) {
3112            // We couldn't find the specific class specified in the Intent.
3113            // Also the end of the line.
3114            err = START_CLASS_NOT_FOUND;
3115        }
3116
3117        ProcessRecord callerApp = null;
3118        if (err == START_SUCCESS && caller != null) {
3119            callerApp = getRecordForAppLocked(caller);
3120            if (callerApp != null) {
3121                callingPid = callerApp.pid;
3122                callingUid = callerApp.info.uid;
3123            } else {
3124                Log.w(TAG, "Unable to find app for caller " + caller
3125                      + " (pid=" + callingPid + ") when starting: "
3126                      + intent.toString());
3127                err = START_PERMISSION_DENIED;
3128            }
3129        }
3130
3131        if (err != START_SUCCESS) {
3132            if (resultRecord != null) {
3133                sendActivityResultLocked(-1,
3134                    resultRecord, resultWho, requestCode,
3135                    Activity.RESULT_CANCELED, null);
3136            }
3137            return err;
3138        }
3139
3140        final int perm = checkComponentPermission(aInfo.permission, callingPid,
3141                callingUid, aInfo.exported ? -1 : aInfo.applicationInfo.uid);
3142        if (perm != PackageManager.PERMISSION_GRANTED) {
3143            if (resultRecord != null) {
3144                sendActivityResultLocked(-1,
3145                    resultRecord, resultWho, requestCode,
3146                    Activity.RESULT_CANCELED, null);
3147            }
3148            String msg = "Permission Denial: starting " + intent.toString()
3149                    + " from " + callerApp + " (pid=" + callingPid
3150                    + ", uid=" + callingUid + ")"
3151                    + " requires " + aInfo.permission;
3152            Log.w(TAG, msg);
3153            throw new SecurityException(msg);
3154        }
3155
3156        if (mController != null) {
3157            boolean abort = false;
3158            try {
3159                // The Intent we give to the watcher has the extra data
3160                // stripped off, since it can contain private information.
3161                Intent watchIntent = intent.cloneFilter();
3162                abort = !mController.activityStarting(watchIntent,
3163                        aInfo.applicationInfo.packageName);
3164            } catch (RemoteException e) {
3165                mController = null;
3166            }
3167
3168            if (abort) {
3169                if (resultRecord != null) {
3170                    sendActivityResultLocked(-1,
3171                        resultRecord, resultWho, requestCode,
3172                        Activity.RESULT_CANCELED, null);
3173                }
3174                // We pretend to the caller that it was really started, but
3175                // they will just get a cancel result.
3176                return START_SUCCESS;
3177            }
3178        }
3179
3180        HistoryRecord r = new HistoryRecord(this, callerApp, callingUid,
3181                intent, resolvedType, aInfo, mConfiguration,
3182                resultRecord, resultWho, requestCode, componentSpecified);
3183
3184        if (mResumedActivity == null
3185                || mResumedActivity.info.applicationInfo.uid != callingUid) {
3186            if (!checkAppSwitchAllowedLocked(callingPid, callingUid, "Activity start")) {
3187                PendingActivityLaunch pal = new PendingActivityLaunch();
3188                pal.r = r;
3189                pal.sourceRecord = sourceRecord;
3190                pal.grantedUriPermissions = grantedUriPermissions;
3191                pal.grantedMode = grantedMode;
3192                pal.onlyIfNeeded = onlyIfNeeded;
3193                mPendingActivityLaunches.add(pal);
3194                return START_SWITCHES_CANCELED;
3195            }
3196        }
3197
3198        if (mDidAppSwitch) {
3199            // This is the second allowed switch since we stopped switches,
3200            // so now just generally allow switches.  Use case: user presses
3201            // home (switches disabled, switch to home, mDidAppSwitch now true);
3202            // user taps a home icon (coming from home so allowed, we hit here
3203            // and now allow anyone to switch again).
3204            mAppSwitchesAllowedTime = 0;
3205        } else {
3206            mDidAppSwitch = true;
3207        }
3208
3209        doPendingActivityLaunchesLocked(false);
3210
3211        return startActivityUncheckedLocked(r, sourceRecord,
3212                grantedUriPermissions, grantedMode, onlyIfNeeded, true);
3213    }
3214
3215    private final void doPendingActivityLaunchesLocked(boolean doResume) {
3216        final int N = mPendingActivityLaunches.size();
3217        if (N <= 0) {
3218            return;
3219        }
3220        for (int i=0; i<N; i++) {
3221            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
3222            startActivityUncheckedLocked(pal.r, pal.sourceRecord,
3223                    pal.grantedUriPermissions, pal.grantedMode, pal.onlyIfNeeded,
3224                    doResume && i == (N-1));
3225        }
3226        mPendingActivityLaunches.clear();
3227    }
3228
3229    private final int startActivityUncheckedLocked(HistoryRecord r,
3230            HistoryRecord sourceRecord, Uri[] grantedUriPermissions,
3231            int grantedMode, boolean onlyIfNeeded, boolean doResume) {
3232        final Intent intent = r.intent;
3233        final int callingUid = r.launchedFromUid;
3234
3235        int launchFlags = intent.getFlags();
3236
3237        // We'll invoke onUserLeaving before onPause only if the launching
3238        // activity did not explicitly state that this is an automated launch.
3239        mUserLeaving = (launchFlags&Intent.FLAG_ACTIVITY_NO_USER_ACTION) == 0;
3240        if (DEBUG_USER_LEAVING) Log.v(TAG,
3241                "startActivity() => mUserLeaving=" + mUserLeaving);
3242
3243        // If the caller has asked not to resume at this point, we make note
3244        // of this in the record so that we can skip it when trying to find
3245        // the top running activity.
3246        if (!doResume) {
3247            r.delayedResume = true;
3248        }
3249
3250        HistoryRecord notTop = (launchFlags&Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP)
3251                != 0 ? r : null;
3252
3253        // If the onlyIfNeeded flag is set, then we can do this if the activity
3254        // being launched is the same as the one making the call...  or, as
3255        // a special case, if we do not know the caller then we count the
3256        // current top activity as the caller.
3257        if (onlyIfNeeded) {
3258            HistoryRecord checkedCaller = sourceRecord;
3259            if (checkedCaller == null) {
3260                checkedCaller = topRunningNonDelayedActivityLocked(notTop);
3261            }
3262            if (!checkedCaller.realActivity.equals(r.realActivity)) {
3263                // Caller is not the same as launcher, so always needed.
3264                onlyIfNeeded = false;
3265            }
3266        }
3267
3268        if (grantedUriPermissions != null && callingUid > 0) {
3269            for (int i=0; i<grantedUriPermissions.length; i++) {
3270                grantUriPermissionLocked(callingUid, r.packageName,
3271                        grantedUriPermissions[i], grantedMode, r);
3272            }
3273        }
3274
3275        grantUriPermissionFromIntentLocked(callingUid, r.packageName,
3276                intent, r);
3277
3278        if (sourceRecord == null) {
3279            // This activity is not being started from another...  in this
3280            // case we -always- start a new task.
3281            if ((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
3282                Log.w(TAG, "startActivity called from non-Activity context; forcing Intent.FLAG_ACTIVITY_NEW_TASK for: "
3283                      + intent);
3284                launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
3285            }
3286        } else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
3287            // The original activity who is starting us is running as a single
3288            // instance...  this new activity it is starting must go on its
3289            // own task.
3290            launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
3291        } else if (r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE
3292                || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
3293            // The activity being started is a single instance...  it always
3294            // gets launched into its own task.
3295            launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
3296        }
3297
3298        if (r.resultTo != null && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
3299            // For whatever reason this activity is being launched into a new
3300            // task...  yet the caller has requested a result back.  Well, that
3301            // is pretty messed up, so instead immediately send back a cancel
3302            // and let the new task continue launched as normal without a
3303            // dependency on its originator.
3304            Log.w(TAG, "Activity is launching as a new task, so cancelling activity result.");
3305            sendActivityResultLocked(-1,
3306                    r.resultTo, r.resultWho, r.requestCode,
3307                Activity.RESULT_CANCELED, null);
3308            r.resultTo = null;
3309        }
3310
3311        boolean addingToTask = false;
3312        if (((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0 &&
3313                (launchFlags&Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
3314                || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
3315                || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
3316            // If bring to front is requested, and no result is requested, and
3317            // we can find a task that was started with this same
3318            // component, then instead of launching bring that one to the front.
3319            if (r.resultTo == null) {
3320                // See if there is a task to bring to the front.  If this is
3321                // a SINGLE_INSTANCE activity, there can be one and only one
3322                // instance of it in the history, and it is always in its own
3323                // unique task, so we do a special search.
3324                HistoryRecord taskTop = r.launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE
3325                        ? findTaskLocked(intent, r.info)
3326                        : findActivityLocked(intent, r.info);
3327                if (taskTop != null) {
3328                    if (taskTop.task.intent == null) {
3329                        // This task was started because of movement of
3330                        // the activity based on affinity...  now that we
3331                        // are actually launching it, we can assign the
3332                        // base intent.
3333                        taskTop.task.setIntent(intent, r.info);
3334                    }
3335                    // If the target task is not in the front, then we need
3336                    // to bring it to the front...  except...  well, with
3337                    // SINGLE_TASK_LAUNCH it's not entirely clear.  We'd like
3338                    // to have the same behavior as if a new instance was
3339                    // being started, which means not bringing it to the front
3340                    // if the caller is not itself in the front.
3341                    HistoryRecord curTop = topRunningNonDelayedActivityLocked(notTop);
3342                    if (curTop.task != taskTop.task) {
3343                        r.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
3344                        boolean callerAtFront = sourceRecord == null
3345                                || curTop.task == sourceRecord.task;
3346                        if (callerAtFront) {
3347                            // We really do want to push this one into the
3348                            // user's face, right now.
3349                            moveTaskToFrontLocked(taskTop.task, r);
3350                        }
3351                    }
3352                    // If the caller has requested that the target task be
3353                    // reset, then do so.
3354                    if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
3355                        taskTop = resetTaskIfNeededLocked(taskTop, r);
3356                    }
3357                    if (onlyIfNeeded) {
3358                        // We don't need to start a new activity, and
3359                        // the client said not to do anything if that
3360                        // is the case, so this is it!  And for paranoia, make
3361                        // sure we have correctly resumed the top activity.
3362                        if (doResume) {
3363                            resumeTopActivityLocked(null);
3364                        }
3365                        return START_RETURN_INTENT_TO_CALLER;
3366                    }
3367                    if ((launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0
3368                            || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
3369                            || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
3370                        // In this situation we want to remove all activities
3371                        // from the task up to the one being started.  In most
3372                        // cases this means we are resetting the task to its
3373                        // initial state.
3374                        HistoryRecord top = performClearTaskLocked(
3375                                taskTop.task.taskId, r, launchFlags, true);
3376                        if (top != null) {
3377                            if (top.frontOfTask) {
3378                                // Activity aliases may mean we use different
3379                                // intents for the top activity, so make sure
3380                                // the task now has the identity of the new
3381                                // intent.
3382                                top.task.setIntent(r.intent, r.info);
3383                            }
3384                            logStartActivity(EventLogTags.AM_NEW_INTENT, r, top.task);
3385                            deliverNewIntentLocked(top, r.intent);
3386                        } else {
3387                            // A special case: we need to
3388                            // start the activity because it is not currently
3389                            // running, and the caller has asked to clear the
3390                            // current task to have this activity at the top.
3391                            addingToTask = true;
3392                            // Now pretend like this activity is being started
3393                            // by the top of its task, so it is put in the
3394                            // right place.
3395                            sourceRecord = taskTop;
3396                        }
3397                    } else if (r.realActivity.equals(taskTop.task.realActivity)) {
3398                        // In this case the top activity on the task is the
3399                        // same as the one being launched, so we take that
3400                        // as a request to bring the task to the foreground.
3401                        // If the top activity in the task is the root
3402                        // activity, deliver this new intent to it if it
3403                        // desires.
3404                        if ((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
3405                                && taskTop.realActivity.equals(r.realActivity)) {
3406                            logStartActivity(EventLogTags.AM_NEW_INTENT, r, taskTop.task);
3407                            if (taskTop.frontOfTask) {
3408                                taskTop.task.setIntent(r.intent, r.info);
3409                            }
3410                            deliverNewIntentLocked(taskTop, r.intent);
3411                        } else if (!r.intent.filterEquals(taskTop.task.intent)) {
3412                            // In this case we are launching the root activity
3413                            // of the task, but with a different intent.  We
3414                            // should start a new instance on top.
3415                            addingToTask = true;
3416                            sourceRecord = taskTop;
3417                        }
3418                    } else if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0) {
3419                        // In this case an activity is being launched in to an
3420                        // existing task, without resetting that task.  This
3421                        // is typically the situation of launching an activity
3422                        // from a notification or shortcut.  We want to place
3423                        // the new activity on top of the current task.
3424                        addingToTask = true;
3425                        sourceRecord = taskTop;
3426                    } else if (!taskTop.task.rootWasReset) {
3427                        // In this case we are launching in to an existing task
3428                        // that has not yet been started from its front door.
3429                        // The current task has been brought to the front.
3430                        // Ideally, we'd probably like to place this new task
3431                        // at the bottom of its stack, but that's a little hard
3432                        // to do with the current organization of the code so
3433                        // for now we'll just drop it.
3434                        taskTop.task.setIntent(r.intent, r.info);
3435                    }
3436                    if (!addingToTask) {
3437                        // We didn't do anything...  but it was needed (a.k.a., client
3438                        // don't use that intent!)  And for paranoia, make
3439                        // sure we have correctly resumed the top activity.
3440                        if (doResume) {
3441                            resumeTopActivityLocked(null);
3442                        }
3443                        return START_TASK_TO_FRONT;
3444                    }
3445                }
3446            }
3447        }
3448
3449        //String uri = r.intent.toURI();
3450        //Intent intent2 = new Intent(uri);
3451        //Log.i(TAG, "Given intent: " + r.intent);
3452        //Log.i(TAG, "URI is: " + uri);
3453        //Log.i(TAG, "To intent: " + intent2);
3454
3455        if (r.packageName != null) {
3456            // If the activity being launched is the same as the one currently
3457            // at the top, then we need to check if it should only be launched
3458            // once.
3459            HistoryRecord top = topRunningNonDelayedActivityLocked(notTop);
3460            if (top != null && r.resultTo == null) {
3461                if (top.realActivity.equals(r.realActivity)) {
3462                    if (top.app != null && top.app.thread != null) {
3463                        if ((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
3464                            || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP
3465                            || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
3466                            logStartActivity(EventLogTags.AM_NEW_INTENT, top, top.task);
3467                            // For paranoia, make sure we have correctly
3468                            // resumed the top activity.
3469                            if (doResume) {
3470                                resumeTopActivityLocked(null);
3471                            }
3472                            if (onlyIfNeeded) {
3473                                // We don't need to start a new activity, and
3474                                // the client said not to do anything if that
3475                                // is the case, so this is it!
3476                                return START_RETURN_INTENT_TO_CALLER;
3477                            }
3478                            deliverNewIntentLocked(top, r.intent);
3479                            return START_DELIVERED_TO_TOP;
3480                        }
3481                    }
3482                }
3483            }
3484
3485        } else {
3486            if (r.resultTo != null) {
3487                sendActivityResultLocked(-1,
3488                        r.resultTo, r.resultWho, r.requestCode,
3489                    Activity.RESULT_CANCELED, null);
3490            }
3491            return START_CLASS_NOT_FOUND;
3492        }
3493
3494        boolean newTask = false;
3495
3496        // Should this be considered a new task?
3497        if (r.resultTo == null && !addingToTask
3498                && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
3499            // todo: should do better management of integers.
3500            mCurTask++;
3501            if (mCurTask <= 0) {
3502                mCurTask = 1;
3503            }
3504            r.task = new TaskRecord(mCurTask, r.info, intent,
3505                    (r.info.flags&ActivityInfo.FLAG_CLEAR_TASK_ON_LAUNCH) != 0);
3506            if (DEBUG_TASKS) Log.v(TAG, "Starting new activity " + r
3507                    + " in new task " + r.task);
3508            newTask = true;
3509            addRecentTask(r.task);
3510
3511        } else if (sourceRecord != null) {
3512            if (!addingToTask &&
3513                    (launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
3514                // In this case, we are adding the activity to an existing
3515                // task, but the caller has asked to clear that task if the
3516                // activity is already running.
3517                HistoryRecord top = performClearTaskLocked(
3518                        sourceRecord.task.taskId, r, launchFlags, true);
3519                if (top != null) {
3520                    logStartActivity(EventLogTags.AM_NEW_INTENT, r, top.task);
3521                    deliverNewIntentLocked(top, r.intent);
3522                    // For paranoia, make sure we have correctly
3523                    // resumed the top activity.
3524                    if (doResume) {
3525                        resumeTopActivityLocked(null);
3526                    }
3527                    return START_DELIVERED_TO_TOP;
3528                }
3529            } else if (!addingToTask &&
3530                    (launchFlags&Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) {
3531                // In this case, we are launching an activity in our own task
3532                // that may already be running somewhere in the history, and
3533                // we want to shuffle it to the front of the stack if so.
3534                int where = findActivityInHistoryLocked(r, sourceRecord.task.taskId);
3535                if (where >= 0) {
3536                    HistoryRecord top = moveActivityToFrontLocked(where);
3537                    logStartActivity(EventLogTags.AM_NEW_INTENT, r, top.task);
3538                    deliverNewIntentLocked(top, r.intent);
3539                    if (doResume) {
3540                        resumeTopActivityLocked(null);
3541                    }
3542                    return START_DELIVERED_TO_TOP;
3543                }
3544            }
3545            // An existing activity is starting this new activity, so we want
3546            // to keep the new one in the same task as the one that is starting
3547            // it.
3548            r.task = sourceRecord.task;
3549            if (DEBUG_TASKS) Log.v(TAG, "Starting new activity " + r
3550                    + " in existing task " + r.task);
3551
3552        } else {
3553            // This not being started from an existing activity, and not part
3554            // of a new task...  just put it in the top task, though these days
3555            // this case should never happen.
3556            final int N = mHistory.size();
3557            HistoryRecord prev =
3558                N > 0 ? (HistoryRecord)mHistory.get(N-1) : null;
3559            r.task = prev != null
3560                ? prev.task
3561                : new TaskRecord(mCurTask, r.info, intent,
3562                        (r.info.flags&ActivityInfo.FLAG_CLEAR_TASK_ON_LAUNCH) != 0);
3563            if (DEBUG_TASKS) Log.v(TAG, "Starting new activity " + r
3564                    + " in new guessed " + r.task);
3565        }
3566        if (newTask) {
3567            EventLog.writeEvent(EventLogTags.AM_CREATE_TASK, r.task.taskId);
3568        }
3569        logStartActivity(EventLogTags.AM_CREATE_ACTIVITY, r, r.task);
3570        startActivityLocked(r, newTask, doResume);
3571        return START_SUCCESS;
3572    }
3573
3574    public final int startActivity(IApplicationThread caller,
3575            Intent intent, String resolvedType, Uri[] grantedUriPermissions,
3576            int grantedMode, IBinder resultTo,
3577            String resultWho, int requestCode, boolean onlyIfNeeded,
3578            boolean debug) {
3579        // Refuse possible leaked file descriptors
3580        if (intent != null && intent.hasFileDescriptors()) {
3581            throw new IllegalArgumentException("File descriptors passed in Intent");
3582        }
3583
3584        final boolean componentSpecified = intent.getComponent() != null;
3585
3586        // Don't modify the client's object!
3587        intent = new Intent(intent);
3588
3589        // Collect information about the target of the Intent.
3590        ActivityInfo aInfo;
3591        try {
3592            ResolveInfo rInfo =
3593                ActivityThread.getPackageManager().resolveIntent(
3594                        intent, resolvedType,
3595                        PackageManager.MATCH_DEFAULT_ONLY
3596                        | STOCK_PM_FLAGS);
3597            aInfo = rInfo != null ? rInfo.activityInfo : null;
3598        } catch (RemoteException e) {
3599            aInfo = null;
3600        }
3601
3602        if (aInfo != null) {
3603            // Store the found target back into the intent, because now that
3604            // we have it we never want to do this again.  For example, if the
3605            // user navigates back to this point in the history, we should
3606            // always restart the exact same activity.
3607            intent.setComponent(new ComponentName(
3608                    aInfo.applicationInfo.packageName, aInfo.name));
3609
3610            // Don't debug things in the system process
3611            if (debug) {
3612                if (!aInfo.processName.equals("system")) {
3613                    setDebugApp(aInfo.processName, true, false);
3614                }
3615            }
3616        }
3617
3618        synchronized(this) {
3619            final long origId = Binder.clearCallingIdentity();
3620            int res = startActivityLocked(caller, intent, resolvedType,
3621                    grantedUriPermissions, grantedMode, aInfo,
3622                    resultTo, resultWho, requestCode, -1, -1,
3623                    onlyIfNeeded, componentSpecified);
3624            Binder.restoreCallingIdentity(origId);
3625            return res;
3626        }
3627    }
3628
3629    public int startActivityIntentSender(IApplicationThread caller,
3630            IntentSender intent, Intent fillInIntent, String resolvedType,
3631            IBinder resultTo, String resultWho, int requestCode,
3632            int flagsMask, int flagsValues) {
3633        // Refuse possible leaked file descriptors
3634        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3635            throw new IllegalArgumentException("File descriptors passed in Intent");
3636        }
3637
3638        IIntentSender sender = intent.getTarget();
3639        if (!(sender instanceof PendingIntentRecord)) {
3640            throw new IllegalArgumentException("Bad PendingIntent object");
3641        }
3642
3643        PendingIntentRecord pir = (PendingIntentRecord)sender;
3644
3645        synchronized (this) {
3646            // If this is coming from the currently resumed activity, it is
3647            // effectively saying that app switches are allowed at this point.
3648            if (mResumedActivity != null
3649                    && mResumedActivity.info.applicationInfo.uid ==
3650                            Binder.getCallingUid()) {
3651                mAppSwitchesAllowedTime = 0;
3652            }
3653        }
3654
3655        return pir.sendInner(0, fillInIntent, resolvedType,
3656                null, resultTo, resultWho, requestCode, flagsMask, flagsValues);
3657    }
3658
3659    public boolean startNextMatchingActivity(IBinder callingActivity,
3660            Intent intent) {
3661        // Refuse possible leaked file descriptors
3662        if (intent != null && intent.hasFileDescriptors() == true) {
3663            throw new IllegalArgumentException("File descriptors passed in Intent");
3664        }
3665
3666        synchronized (this) {
3667            int index = indexOfTokenLocked(callingActivity);
3668            if (index < 0) {
3669                return false;
3670            }
3671            HistoryRecord r = (HistoryRecord)mHistory.get(index);
3672            if (r.app == null || r.app.thread == null) {
3673                // The caller is not running...  d'oh!
3674                return false;
3675            }
3676            intent = new Intent(intent);
3677            // The caller is not allowed to change the data.
3678            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3679            // And we are resetting to find the next component...
3680            intent.setComponent(null);
3681
3682            ActivityInfo aInfo = null;
3683            try {
3684                List<ResolveInfo> resolves =
3685                    ActivityThread.getPackageManager().queryIntentActivities(
3686                            intent, r.resolvedType,
3687                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS);
3688
3689                // Look for the original activity in the list...
3690                final int N = resolves != null ? resolves.size() : 0;
3691                for (int i=0; i<N; i++) {
3692                    ResolveInfo rInfo = resolves.get(i);
3693                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3694                            && rInfo.activityInfo.name.equals(r.info.name)) {
3695                        // We found the current one...  the next matching is
3696                        // after it.
3697                        i++;
3698                        if (i<N) {
3699                            aInfo = resolves.get(i).activityInfo;
3700                        }
3701                        break;
3702                    }
3703                }
3704            } catch (RemoteException e) {
3705            }
3706
3707            if (aInfo == null) {
3708                // Nobody who is next!
3709                return false;
3710            }
3711
3712            intent.setComponent(new ComponentName(
3713                    aInfo.applicationInfo.packageName, aInfo.name));
3714            intent.setFlags(intent.getFlags()&~(
3715                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3716                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3717                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3718                    Intent.FLAG_ACTIVITY_NEW_TASK));
3719
3720            // Okay now we need to start the new activity, replacing the
3721            // currently running activity.  This is a little tricky because
3722            // we want to start the new one as if the current one is finished,
3723            // but not finish the current one first so that there is no flicker.
3724            // And thus...
3725            final boolean wasFinishing = r.finishing;
3726            r.finishing = true;
3727
3728            // Propagate reply information over to the new activity.
3729            final HistoryRecord resultTo = r.resultTo;
3730            final String resultWho = r.resultWho;
3731            final int requestCode = r.requestCode;
3732            r.resultTo = null;
3733            if (resultTo != null) {
3734                resultTo.removeResultsLocked(r, resultWho, requestCode);
3735            }
3736
3737            final long origId = Binder.clearCallingIdentity();
3738            // XXX we are not dealing with propagating grantedUriPermissions...
3739            // those are not yet exposed to user code, so there is no need.
3740            int res = startActivityLocked(r.app.thread, intent,
3741                    r.resolvedType, null, 0, aInfo, resultTo, resultWho,
3742                    requestCode, -1, r.launchedFromUid, false, false);
3743            Binder.restoreCallingIdentity(origId);
3744
3745            r.finishing = wasFinishing;
3746            if (res != START_SUCCESS) {
3747                return false;
3748            }
3749            return true;
3750        }
3751    }
3752
3753    public final int startActivityInPackage(int uid,
3754            Intent intent, String resolvedType, IBinder resultTo,
3755            String resultWho, int requestCode, boolean onlyIfNeeded) {
3756
3757        // This is so super not safe, that only the system (or okay root)
3758        // can do it.
3759        final int callingUid = Binder.getCallingUid();
3760        if (callingUid != 0 && callingUid != Process.myUid()) {
3761            throw new SecurityException(
3762                    "startActivityInPackage only available to the system");
3763        }
3764
3765        final boolean componentSpecified = intent.getComponent() != null;
3766
3767        // Don't modify the client's object!
3768        intent = new Intent(intent);
3769
3770        // Collect information about the target of the Intent.
3771        ActivityInfo aInfo;
3772        try {
3773            ResolveInfo rInfo =
3774                ActivityThread.getPackageManager().resolveIntent(
3775                        intent, resolvedType,
3776                        PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS);
3777            aInfo = rInfo != null ? rInfo.activityInfo : null;
3778        } catch (RemoteException e) {
3779            aInfo = null;
3780        }
3781
3782        if (aInfo != null) {
3783            // Store the found target back into the intent, because now that
3784            // we have it we never want to do this again.  For example, if the
3785            // user navigates back to this point in the history, we should
3786            // always restart the exact same activity.
3787            intent.setComponent(new ComponentName(
3788                    aInfo.applicationInfo.packageName, aInfo.name));
3789        }
3790
3791        synchronized(this) {
3792            return startActivityLocked(null, intent, resolvedType,
3793                    null, 0, aInfo, resultTo, resultWho, requestCode, -1, uid,
3794                    onlyIfNeeded, componentSpecified);
3795        }
3796    }
3797
3798    private final void addRecentTask(TaskRecord task) {
3799        // Remove any existing entries that are the same kind of task.
3800        int N = mRecentTasks.size();
3801        for (int i=0; i<N; i++) {
3802            TaskRecord tr = mRecentTasks.get(i);
3803            if ((task.affinity != null && task.affinity.equals(tr.affinity))
3804                    || (task.intent != null && task.intent.filterEquals(tr.intent))) {
3805                mRecentTasks.remove(i);
3806                i--;
3807                N--;
3808                if (task.intent == null) {
3809                    // If the new recent task we are adding is not fully
3810                    // specified, then replace it with the existing recent task.
3811                    task = tr;
3812                }
3813            }
3814        }
3815        if (N >= MAX_RECENT_TASKS) {
3816            mRecentTasks.remove(N-1);
3817        }
3818        mRecentTasks.add(0, task);
3819    }
3820
3821    public void setRequestedOrientation(IBinder token,
3822            int requestedOrientation) {
3823        synchronized (this) {
3824            int index = indexOfTokenLocked(token);
3825            if (index < 0) {
3826                return;
3827            }
3828            HistoryRecord r = (HistoryRecord)mHistory.get(index);
3829            final long origId = Binder.clearCallingIdentity();
3830            mWindowManager.setAppOrientation(r, requestedOrientation);
3831            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3832                    mConfiguration,
3833                    r.mayFreezeScreenLocked(r.app) ? r : null);
3834            if (config != null) {
3835                r.frozenBeforeDestroy = true;
3836                if (!updateConfigurationLocked(config, r)) {
3837                    resumeTopActivityLocked(null);
3838                }
3839            }
3840            Binder.restoreCallingIdentity(origId);
3841        }
3842    }
3843
3844    public int getRequestedOrientation(IBinder token) {
3845        synchronized (this) {
3846            int index = indexOfTokenLocked(token);
3847            if (index < 0) {
3848                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3849            }
3850            HistoryRecord r = (HistoryRecord)mHistory.get(index);
3851            return mWindowManager.getAppOrientation(r);
3852        }
3853    }
3854
3855    private final void stopActivityLocked(HistoryRecord r) {
3856        if (DEBUG_SWITCH) Log.d(TAG, "Stopping: " + r);
3857        if ((r.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_HISTORY) != 0
3858                || (r.info.flags&ActivityInfo.FLAG_NO_HISTORY) != 0) {
3859            if (!r.finishing) {
3860                requestFinishActivityLocked(r, Activity.RESULT_CANCELED, null,
3861                        "no-history");
3862            }
3863        } else if (r.app != null && r.app.thread != null) {
3864            if (mFocusedActivity == r) {
3865                setFocusedActivityLocked(topRunningActivityLocked(null));
3866            }
3867            r.resumeKeyDispatchingLocked();
3868            try {
3869                r.stopped = false;
3870                r.state = ActivityState.STOPPING;
3871                if (DEBUG_VISBILITY) Log.v(
3872                        TAG, "Stopping visible=" + r.visible + " for " + r);
3873                if (!r.visible) {
3874                    mWindowManager.setAppVisibility(r, false);
3875                }
3876                r.app.thread.scheduleStopActivity(r, r.visible, r.configChangeFlags);
3877            } catch (Exception e) {
3878                // Maybe just ignore exceptions here...  if the process
3879                // has crashed, our death notification will clean things
3880                // up.
3881                Log.w(TAG, "Exception thrown during pause", e);
3882                // Just in case, assume it to be stopped.
3883                r.stopped = true;
3884                r.state = ActivityState.STOPPED;
3885                if (r.configDestroy) {
3886                    destroyActivityLocked(r, true);
3887                }
3888            }
3889        }
3890    }
3891
3892    /**
3893     * @return Returns true if the activity is being finished, false if for
3894     * some reason it is being left as-is.
3895     */
3896    private final boolean requestFinishActivityLocked(IBinder token, int resultCode,
3897            Intent resultData, String reason) {
3898        if (DEBUG_RESULTS) Log.v(
3899            TAG, "Finishing activity: token=" + token
3900            + ", result=" + resultCode + ", data=" + resultData);
3901
3902        int index = indexOfTokenLocked(token);
3903        if (index < 0) {
3904            return false;
3905        }
3906        HistoryRecord r = (HistoryRecord)mHistory.get(index);
3907
3908        // Is this the last activity left?
3909        boolean lastActivity = true;
3910        for (int i=mHistory.size()-1; i>=0; i--) {
3911            HistoryRecord p = (HistoryRecord)mHistory.get(i);
3912            if (!p.finishing && p != r) {
3913                lastActivity = false;
3914                break;
3915            }
3916        }
3917
3918        // If this is the last activity, but it is the home activity, then
3919        // just don't finish it.
3920        if (lastActivity) {
3921            if (r.intent.hasCategory(Intent.CATEGORY_HOME)) {
3922                return false;
3923            }
3924        }
3925
3926        finishActivityLocked(r, index, resultCode, resultData, reason);
3927        return true;
3928    }
3929
3930    /**
3931     * @return Returns true if this activity has been removed from the history
3932     * list, or false if it is still in the list and will be removed later.
3933     */
3934    private final boolean finishActivityLocked(HistoryRecord r, int index,
3935            int resultCode, Intent resultData, String reason) {
3936        if (r.finishing) {
3937            Log.w(TAG, "Duplicate finish request for " + r);
3938            return false;
3939        }
3940
3941        r.finishing = true;
3942        EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY,
3943                System.identityHashCode(r),
3944                r.task.taskId, r.shortComponentName, reason);
3945        r.task.numActivities--;
3946        if (r.frontOfTask && index < (mHistory.size()-1)) {
3947            HistoryRecord next = (HistoryRecord)mHistory.get(index+1);
3948            if (next.task == r.task) {
3949                next.frontOfTask = true;
3950            }
3951        }
3952
3953        r.pauseKeyDispatchingLocked();
3954        if (mFocusedActivity == r) {
3955            setFocusedActivityLocked(topRunningActivityLocked(null));
3956        }
3957
3958        // send the result
3959        HistoryRecord resultTo = r.resultTo;
3960        if (resultTo != null) {
3961            if (DEBUG_RESULTS) Log.v(TAG, "Adding result to " + resultTo
3962                    + " who=" + r.resultWho + " req=" + r.requestCode
3963                    + " res=" + resultCode + " data=" + resultData);
3964            if (r.info.applicationInfo.uid > 0) {
3965                grantUriPermissionFromIntentLocked(r.info.applicationInfo.uid,
3966                        r.packageName, resultData, r);
3967            }
3968            resultTo.addResultLocked(r, r.resultWho, r.requestCode, resultCode,
3969                                     resultData);
3970            r.resultTo = null;
3971        }
3972        else if (DEBUG_RESULTS) Log.v(TAG, "No result destination from " + r);
3973
3974        // Make sure this HistoryRecord is not holding on to other resources,
3975        // because clients have remote IPC references to this object so we
3976        // can't assume that will go away and want to avoid circular IPC refs.
3977        r.results = null;
3978        r.pendingResults = null;
3979        r.newIntents = null;
3980        r.icicle = null;
3981
3982        if (mPendingThumbnails.size() > 0) {
3983            // There are clients waiting to receive thumbnails so, in case
3984            // this is an activity that someone is waiting for, add it
3985            // to the pending list so we can correctly update the clients.
3986            mCancelledThumbnails.add(r);
3987        }
3988
3989        if (mResumedActivity == r) {
3990            boolean endTask = index <= 0
3991                    || ((HistoryRecord)mHistory.get(index-1)).task != r.task;
3992            if (DEBUG_TRANSITION) Log.v(TAG,
3993                    "Prepare close transition: finishing " + r);
3994            mWindowManager.prepareAppTransition(endTask
3995                    ? WindowManagerPolicy.TRANSIT_TASK_CLOSE
3996                    : WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE);
3997
3998            // Tell window manager to prepare for this one to be removed.
3999            mWindowManager.setAppVisibility(r, false);
4000
4001            if (mPausingActivity == null) {
4002                if (DEBUG_PAUSE) Log.v(TAG, "Finish needs to pause: " + r);
4003                if (DEBUG_USER_LEAVING) Log.v(TAG, "finish() => pause with userLeaving=false");
4004                startPausingLocked(false, false);
4005            }
4006
4007        } else if (r.state != ActivityState.PAUSING) {
4008            // If the activity is PAUSING, we will complete the finish once
4009            // it is done pausing; else we can just directly finish it here.
4010            if (DEBUG_PAUSE) Log.v(TAG, "Finish not pausing: " + r);
4011            return finishCurrentActivityLocked(r, index,
4012                    FINISH_AFTER_PAUSE) == null;
4013        } else {
4014            if (DEBUG_PAUSE) Log.v(TAG, "Finish waiting for pause of: " + r);
4015        }
4016
4017        return false;
4018    }
4019
4020    private static final int FINISH_IMMEDIATELY = 0;
4021    private static final int FINISH_AFTER_PAUSE = 1;
4022    private static final int FINISH_AFTER_VISIBLE = 2;
4023
4024    private final HistoryRecord finishCurrentActivityLocked(HistoryRecord r,
4025            int mode) {
4026        final int index = indexOfTokenLocked(r);
4027        if (index < 0) {
4028            return null;
4029        }
4030
4031        return finishCurrentActivityLocked(r, index, mode);
4032    }
4033
4034    private final HistoryRecord finishCurrentActivityLocked(HistoryRecord r,
4035            int index, int mode) {
4036        // First things first: if this activity is currently visible,
4037        // and the resumed activity is not yet visible, then hold off on
4038        // finishing until the resumed one becomes visible.
4039        if (mode == FINISH_AFTER_VISIBLE && r.nowVisible) {
4040            if (!mStoppingActivities.contains(r)) {
4041                mStoppingActivities.add(r);
4042                if (mStoppingActivities.size() > 3) {
4043                    // If we already have a few activities waiting to stop,
4044                    // then give up on things going idle and start clearing
4045                    // them out.
4046                    Message msg = Message.obtain();
4047                    msg.what = ActivityManagerService.IDLE_NOW_MSG;
4048                    mHandler.sendMessage(msg);
4049                }
4050            }
4051            r.state = ActivityState.STOPPING;
4052            updateOomAdjLocked();
4053            return r;
4054        }
4055
4056        // make sure the record is cleaned out of other places.
4057        mStoppingActivities.remove(r);
4058        mWaitingVisibleActivities.remove(r);
4059        if (mResumedActivity == r) {
4060            mResumedActivity = null;
4061        }
4062        final ActivityState prevState = r.state;
4063        r.state = ActivityState.FINISHING;
4064
4065        if (mode == FINISH_IMMEDIATELY
4066                || prevState == ActivityState.STOPPED
4067                || prevState == ActivityState.INITIALIZING) {
4068            // If this activity is already stopped, we can just finish
4069            // it right now.
4070            return destroyActivityLocked(r, true) ? null : r;
4071        } else {
4072            // Need to go through the full pause cycle to get this
4073            // activity into the stopped state and then finish it.
4074            if (localLOGV) Log.v(TAG, "Enqueueing pending finish: " + r);
4075            mFinishingActivities.add(r);
4076            resumeTopActivityLocked(null);
4077        }
4078        return r;
4079    }
4080
4081    /**
4082     * This is the internal entry point for handling Activity.finish().
4083     *
4084     * @param token The Binder token referencing the Activity we want to finish.
4085     * @param resultCode Result code, if any, from this Activity.
4086     * @param resultData Result data (Intent), if any, from this Activity.
4087     *
4088     * @return Returns true if the activity successfully finished, or false if it is still running.
4089     */
4090    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
4091        // Refuse possible leaked file descriptors
4092        if (resultData != null && resultData.hasFileDescriptors() == true) {
4093            throw new IllegalArgumentException("File descriptors passed in Intent");
4094        }
4095
4096        synchronized(this) {
4097            if (mController != null) {
4098                // Find the first activity that is not finishing.
4099                HistoryRecord next = topRunningActivityLocked(token, 0);
4100                if (next != null) {
4101                    // ask watcher if this is allowed
4102                    boolean resumeOK = true;
4103                    try {
4104                        resumeOK = mController.activityResuming(next.packageName);
4105                    } catch (RemoteException e) {
4106                        mController = null;
4107                    }
4108
4109                    if (!resumeOK) {
4110                        return false;
4111                    }
4112                }
4113            }
4114            final long origId = Binder.clearCallingIdentity();
4115            boolean res = requestFinishActivityLocked(token, resultCode,
4116                    resultData, "app-request");
4117            Binder.restoreCallingIdentity(origId);
4118            return res;
4119        }
4120    }
4121
4122    void sendActivityResultLocked(int callingUid, HistoryRecord r,
4123            String resultWho, int requestCode, int resultCode, Intent data) {
4124
4125        if (callingUid > 0) {
4126            grantUriPermissionFromIntentLocked(callingUid, r.packageName,
4127                    data, r);
4128        }
4129
4130        if (DEBUG_RESULTS) Log.v(TAG, "Send activity result to " + r
4131                + " : who=" + resultWho + " req=" + requestCode
4132                + " res=" + resultCode + " data=" + data);
4133        if (mResumedActivity == r && r.app != null && r.app.thread != null) {
4134            try {
4135                ArrayList<ResultInfo> list = new ArrayList<ResultInfo>();
4136                list.add(new ResultInfo(resultWho, requestCode,
4137                        resultCode, data));
4138                r.app.thread.scheduleSendResult(r, list);
4139                return;
4140            } catch (Exception e) {
4141                Log.w(TAG, "Exception thrown sending result to " + r, e);
4142            }
4143        }
4144
4145        r.addResultLocked(null, resultWho, requestCode, resultCode, data);
4146    }
4147
4148    public final void finishSubActivity(IBinder token, String resultWho,
4149            int requestCode) {
4150        synchronized(this) {
4151            int index = indexOfTokenLocked(token);
4152            if (index < 0) {
4153                return;
4154            }
4155            HistoryRecord self = (HistoryRecord)mHistory.get(index);
4156
4157            final long origId = Binder.clearCallingIdentity();
4158
4159            int i;
4160            for (i=mHistory.size()-1; i>=0; i--) {
4161                HistoryRecord r = (HistoryRecord)mHistory.get(i);
4162                if (r.resultTo == self && r.requestCode == requestCode) {
4163                    if ((r.resultWho == null && resultWho == null) ||
4164                        (r.resultWho != null && r.resultWho.equals(resultWho))) {
4165                        finishActivityLocked(r, i,
4166                                Activity.RESULT_CANCELED, null, "request-sub");
4167                    }
4168                }
4169            }
4170
4171            Binder.restoreCallingIdentity(origId);
4172        }
4173    }
4174
4175    public void overridePendingTransition(IBinder token, String packageName,
4176            int enterAnim, int exitAnim) {
4177        synchronized(this) {
4178            int index = indexOfTokenLocked(token);
4179            if (index < 0) {
4180                return;
4181            }
4182            HistoryRecord self = (HistoryRecord)mHistory.get(index);
4183
4184            final long origId = Binder.clearCallingIdentity();
4185
4186            if (self.state == ActivityState.RESUMED
4187                    || self.state == ActivityState.PAUSING) {
4188                mWindowManager.overridePendingAppTransition(packageName,
4189                        enterAnim, exitAnim);
4190            }
4191
4192            Binder.restoreCallingIdentity(origId);
4193        }
4194    }
4195
4196    /**
4197     * Perform clean-up of service connections in an activity record.
4198     */
4199    private final void cleanUpActivityServicesLocked(HistoryRecord r) {
4200        // Throw away any services that have been bound by this activity.
4201        if (r.connections != null) {
4202            Iterator<ConnectionRecord> it = r.connections.iterator();
4203            while (it.hasNext()) {
4204                ConnectionRecord c = it.next();
4205                removeConnectionLocked(c, null, r);
4206            }
4207            r.connections = null;
4208        }
4209    }
4210
4211    /**
4212     * Perform the common clean-up of an activity record.  This is called both
4213     * as part of destroyActivityLocked() (when destroying the client-side
4214     * representation) and cleaning things up as a result of its hosting
4215     * processing going away, in which case there is no remaining client-side
4216     * state to destroy so only the cleanup here is needed.
4217     */
4218    private final void cleanUpActivityLocked(HistoryRecord r, boolean cleanServices) {
4219        if (mResumedActivity == r) {
4220            mResumedActivity = null;
4221        }
4222        if (mFocusedActivity == r) {
4223            mFocusedActivity = null;
4224        }
4225
4226        r.configDestroy = false;
4227        r.frozenBeforeDestroy = false;
4228
4229        // Make sure this record is no longer in the pending finishes list.
4230        // This could happen, for example, if we are trimming activities
4231        // down to the max limit while they are still waiting to finish.
4232        mFinishingActivities.remove(r);
4233        mWaitingVisibleActivities.remove(r);
4234
4235        // Remove any pending results.
4236        if (r.finishing && r.pendingResults != null) {
4237            for (WeakReference<PendingIntentRecord> apr : r.pendingResults) {
4238                PendingIntentRecord rec = apr.get();
4239                if (rec != null) {
4240                    cancelIntentSenderLocked(rec, false);
4241                }
4242            }
4243            r.pendingResults = null;
4244        }
4245
4246        if (cleanServices) {
4247            cleanUpActivityServicesLocked(r);
4248        }
4249
4250        if (mPendingThumbnails.size() > 0) {
4251            // There are clients waiting to receive thumbnails so, in case
4252            // this is an activity that someone is waiting for, add it
4253            // to the pending list so we can correctly update the clients.
4254            mCancelledThumbnails.add(r);
4255        }
4256
4257        // Get rid of any pending idle timeouts.
4258        mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);
4259        mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
4260    }
4261
4262    private final void removeActivityFromHistoryLocked(HistoryRecord r) {
4263        if (r.state != ActivityState.DESTROYED) {
4264            mHistory.remove(r);
4265            r.inHistory = false;
4266            r.state = ActivityState.DESTROYED;
4267            mWindowManager.removeAppToken(r);
4268            if (VALIDATE_TOKENS) {
4269                mWindowManager.validateAppTokens(mHistory);
4270            }
4271            cleanUpActivityServicesLocked(r);
4272            removeActivityUriPermissionsLocked(r);
4273        }
4274    }
4275
4276    /**
4277     * Destroy the current CLIENT SIDE instance of an activity.  This may be
4278     * called both when actually finishing an activity, or when performing
4279     * a configuration switch where we destroy the current client-side object
4280     * but then create a new client-side object for this same HistoryRecord.
4281     */
4282    private final boolean destroyActivityLocked(HistoryRecord r,
4283            boolean removeFromApp) {
4284        if (DEBUG_SWITCH) Log.v(
4285            TAG, "Removing activity: token=" + r
4286              + ", app=" + (r.app != null ? r.app.processName : "(null)"));
4287        EventLog.writeEvent(EventLogTags.AM_DESTROY_ACTIVITY,
4288                System.identityHashCode(r),
4289                r.task.taskId, r.shortComponentName);
4290
4291        boolean removedFromHistory = false;
4292
4293        cleanUpActivityLocked(r, false);
4294
4295        final boolean hadApp = r.app != null;
4296
4297        if (hadApp) {
4298            if (removeFromApp) {
4299                int idx = r.app.activities.indexOf(r);
4300                if (idx >= 0) {
4301                    r.app.activities.remove(idx);
4302                }
4303                if (r.persistent) {
4304                    decPersistentCountLocked(r.app);
4305                }
4306                if (r.app.activities.size() == 0) {
4307                    // No longer have activities, so update location in
4308                    // LRU list.
4309                    updateLruProcessLocked(r.app, true, false);
4310                }
4311            }
4312
4313            boolean skipDestroy = false;
4314
4315            try {
4316                if (DEBUG_SWITCH) Log.i(TAG, "Destroying: " + r);
4317                r.app.thread.scheduleDestroyActivity(r, r.finishing,
4318                        r.configChangeFlags);
4319            } catch (Exception e) {
4320                // We can just ignore exceptions here...  if the process
4321                // has crashed, our death notification will clean things
4322                // up.
4323                //Log.w(TAG, "Exception thrown during finish", e);
4324                if (r.finishing) {
4325                    removeActivityFromHistoryLocked(r);
4326                    removedFromHistory = true;
4327                    skipDestroy = true;
4328                }
4329            }
4330
4331            r.app = null;
4332            r.nowVisible = false;
4333
4334            if (r.finishing && !skipDestroy) {
4335                r.state = ActivityState.DESTROYING;
4336                Message msg = mHandler.obtainMessage(DESTROY_TIMEOUT_MSG);
4337                msg.obj = r;
4338                mHandler.sendMessageDelayed(msg, DESTROY_TIMEOUT);
4339            } else {
4340                r.state = ActivityState.DESTROYED;
4341            }
4342        } else {
4343            // remove this record from the history.
4344            if (r.finishing) {
4345                removeActivityFromHistoryLocked(r);
4346                removedFromHistory = true;
4347            } else {
4348                r.state = ActivityState.DESTROYED;
4349            }
4350        }
4351
4352        r.configChangeFlags = 0;
4353
4354        if (!mLRUActivities.remove(r) && hadApp) {
4355            Log.w(TAG, "Activity " + r + " being finished, but not in LRU list");
4356        }
4357
4358        return removedFromHistory;
4359    }
4360
4361    private static void removeHistoryRecordsForAppLocked(ArrayList list, ProcessRecord app) {
4362        int i = list.size();
4363        if (localLOGV) Log.v(
4364            TAG, "Removing app " + app + " from list " + list
4365            + " with " + i + " entries");
4366        while (i > 0) {
4367            i--;
4368            HistoryRecord r = (HistoryRecord)list.get(i);
4369            if (localLOGV) Log.v(
4370                TAG, "Record #" + i + " " + r + ": app=" + r.app);
4371            if (r.app == app) {
4372                if (localLOGV) Log.v(TAG, "Removing this entry!");
4373                list.remove(i);
4374            }
4375        }
4376    }
4377
4378    /**
4379     * Main function for removing an existing process from the activity manager
4380     * as a result of that process going away.  Clears out all connections
4381     * to the process.
4382     */
4383    private final void handleAppDiedLocked(ProcessRecord app,
4384            boolean restarting) {
4385        cleanUpApplicationRecordLocked(app, restarting, -1);
4386        if (!restarting) {
4387            mLruProcesses.remove(app);
4388        }
4389
4390        // Just in case...
4391        if (mPausingActivity != null && mPausingActivity.app == app) {
4392            if (DEBUG_PAUSE) Log.v(TAG, "App died while pausing: " + mPausingActivity);
4393            mPausingActivity = null;
4394        }
4395        if (mLastPausedActivity != null && mLastPausedActivity.app == app) {
4396            mLastPausedActivity = null;
4397        }
4398
4399        // Remove this application's activities from active lists.
4400        removeHistoryRecordsForAppLocked(mLRUActivities, app);
4401        removeHistoryRecordsForAppLocked(mStoppingActivities, app);
4402        removeHistoryRecordsForAppLocked(mWaitingVisibleActivities, app);
4403        removeHistoryRecordsForAppLocked(mFinishingActivities, app);
4404
4405        boolean atTop = true;
4406        boolean hasVisibleActivities = false;
4407
4408        // Clean out the history list.
4409        int i = mHistory.size();
4410        if (localLOGV) Log.v(
4411            TAG, "Removing app " + app + " from history with " + i + " entries");
4412        while (i > 0) {
4413            i--;
4414            HistoryRecord r = (HistoryRecord)mHistory.get(i);
4415            if (localLOGV) Log.v(
4416                TAG, "Record #" + i + " " + r + ": app=" + r.app);
4417            if (r.app == app) {
4418                if ((!r.haveState && !r.stateNotNeeded) || r.finishing) {
4419                    if (localLOGV) Log.v(
4420                        TAG, "Removing this entry!  frozen=" + r.haveState
4421                        + " finishing=" + r.finishing);
4422                    mHistory.remove(i);
4423
4424                    r.inHistory = false;
4425                    mWindowManager.removeAppToken(r);
4426                    if (VALIDATE_TOKENS) {
4427                        mWindowManager.validateAppTokens(mHistory);
4428                    }
4429                    removeActivityUriPermissionsLocked(r);
4430
4431                } else {
4432                    // We have the current state for this activity, so
4433                    // it can be restarted later when needed.
4434                    if (localLOGV) Log.v(
4435                        TAG, "Keeping entry, setting app to null");
4436                    if (r.visible) {
4437                        hasVisibleActivities = true;
4438                    }
4439                    r.app = null;
4440                    r.nowVisible = false;
4441                    if (!r.haveState) {
4442                        r.icicle = null;
4443                    }
4444                }
4445
4446                cleanUpActivityLocked(r, true);
4447                r.state = ActivityState.STOPPED;
4448            }
4449            atTop = false;
4450        }
4451
4452        app.activities.clear();
4453
4454        if (app.instrumentationClass != null) {
4455            Log.w(TAG, "Crash of app " + app.processName
4456                  + " running instrumentation " + app.instrumentationClass);
4457            Bundle info = new Bundle();
4458            info.putString("shortMsg", "Process crashed.");
4459            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4460        }
4461
4462        if (!restarting) {
4463            if (!resumeTopActivityLocked(null)) {
4464                // If there was nothing to resume, and we are not already
4465                // restarting this process, but there is a visible activity that
4466                // is hosted by the process...  then make sure all visible
4467                // activities are running, taking care of restarting this
4468                // process.
4469                if (hasVisibleActivities) {
4470                    ensureActivitiesVisibleLocked(null, 0);
4471                }
4472            }
4473        }
4474    }
4475
4476    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4477        IBinder threadBinder = thread.asBinder();
4478
4479        // Find the application record.
4480        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4481            ProcessRecord rec = mLruProcesses.get(i);
4482            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4483                return i;
4484            }
4485        }
4486        return -1;
4487    }
4488
4489    private final ProcessRecord getRecordForAppLocked(
4490            IApplicationThread thread) {
4491        if (thread == null) {
4492            return null;
4493        }
4494
4495        int appIndex = getLRURecordIndexForAppLocked(thread);
4496        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4497    }
4498
4499    private final void appDiedLocked(ProcessRecord app, int pid,
4500            IApplicationThread thread) {
4501
4502        mProcDeaths[0]++;
4503
4504        if (app.thread != null && app.thread.asBinder() == thread.asBinder()) {
4505            Log.i(TAG, "Process " + app.processName + " (pid " + pid
4506                    + ") has died.");
4507            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
4508            if (localLOGV) Log.v(
4509                TAG, "Dying app: " + app + ", pid: " + pid
4510                + ", thread: " + thread.asBinder());
4511            boolean doLowMem = app.instrumentationClass == null;
4512            handleAppDiedLocked(app, false);
4513
4514            if (doLowMem) {
4515                // If there are no longer any background processes running,
4516                // and the app that died was not running instrumentation,
4517                // then tell everyone we are now low on memory.
4518                boolean haveBg = false;
4519                for (int i=mLruProcesses.size()-1; i>=0; i--) {
4520                    ProcessRecord rec = mLruProcesses.get(i);
4521                    if (rec.thread != null && rec.setAdj >= HIDDEN_APP_MIN_ADJ) {
4522                        haveBg = true;
4523                        break;
4524                    }
4525                }
4526
4527                if (!haveBg) {
4528                    Log.i(TAG, "Low Memory: No more background processes.");
4529                    EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4530                    long now = SystemClock.uptimeMillis();
4531                    for (int i=mLruProcesses.size()-1; i>=0; i--) {
4532                        ProcessRecord rec = mLruProcesses.get(i);
4533                        if (rec != app && rec.thread != null &&
4534                                (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4535                            // The low memory report is overriding any current
4536                            // state for a GC request.  Make sure to do
4537                            // visible/foreground processes first.
4538                            if (rec.setAdj <= VISIBLE_APP_ADJ) {
4539                                rec.lastRequestedGc = 0;
4540                            } else {
4541                                rec.lastRequestedGc = rec.lastLowMemory;
4542                            }
4543                            rec.reportLowMemory = true;
4544                            rec.lastLowMemory = now;
4545                            mProcessesToGc.remove(rec);
4546                            addProcessToGcListLocked(rec);
4547                        }
4548                    }
4549                    scheduleAppGcsLocked();
4550                }
4551            }
4552        } else if (DEBUG_PROCESSES) {
4553            Log.d(TAG, "Received spurious death notification for thread "
4554                    + thread.asBinder());
4555        }
4556    }
4557
4558    final String readFile(String filename) {
4559        try {
4560            FileInputStream fs = new FileInputStream(filename);
4561            byte[] inp = new byte[8192];
4562            int size = fs.read(inp);
4563            fs.close();
4564            return new String(inp, 0, 0, size);
4565        } catch (java.io.IOException e) {
4566        }
4567        return "";
4568    }
4569
4570    final void appNotRespondingLocked(ProcessRecord app, HistoryRecord activity,
4571            HistoryRecord reportedActivity, final String annotation) {
4572        if (app.notResponding || app.crashing) {
4573            return;
4574        }
4575
4576        // Log the ANR to the event log.
4577        EventLog.writeEvent(EventLogTags.ANR, app.pid, app.processName, annotation);
4578
4579        // If we are on a secure build and the application is not interesting to the user (it is
4580        // not visible or in the background), just kill it instead of displaying a dialog.
4581        boolean isSecure = "1".equals(SystemProperties.get(SYSTEM_SECURE, "0"));
4582        if (isSecure && !app.isInterestingToUserLocked() && Process.myPid() != app.pid) {
4583            Process.killProcess(app.pid);
4584            return;
4585        }
4586
4587        // DeviceMonitor.start();
4588
4589        String processInfo = null;
4590        if (MONITOR_CPU_USAGE) {
4591            updateCpuStatsNow();
4592            synchronized (mProcessStatsThread) {
4593                processInfo = mProcessStats.printCurrentState();
4594            }
4595        }
4596
4597        StringBuilder info = mStringBuilder;
4598        info.setLength(0);
4599        info.append("ANR in process: ");
4600        info.append(app.processName);
4601        if (reportedActivity != null && reportedActivity.app != null) {
4602            info.append(" (last in ");
4603            info.append(reportedActivity.app.processName);
4604            info.append(")");
4605        }
4606        if (annotation != null) {
4607            info.append("\nAnnotation: ");
4608            info.append(annotation);
4609        }
4610        if (MONITOR_CPU_USAGE) {
4611            info.append("\nCPU usage:\n");
4612            info.append(processInfo);
4613        }
4614        Log.i(TAG, info.toString());
4615
4616        // The application is not responding. Dump as many thread traces as we can.
4617        boolean fileDump = prepareTraceFile(true);
4618        if (!fileDump) {
4619            // Dumping traces to the log, just dump the process that isn't responding so
4620            // we don't overflow the log
4621            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4622        } else {
4623            // Dumping traces to a file so dump all active processes we know about
4624            synchronized (this) {
4625                // First, these are the most important processes.
4626                final int[] imppids = new int[3];
4627                int i=0;
4628                imppids[0] = app.pid;
4629                i++;
4630                if (reportedActivity != null && reportedActivity.app != null
4631                        && reportedActivity.app.thread != null
4632                        && reportedActivity.app.pid != app.pid) {
4633                    imppids[i] = reportedActivity.app.pid;
4634                    i++;
4635                }
4636                imppids[i] = Process.myPid();
4637                for (i=0; i<imppids.length && imppids[i] != 0; i++) {
4638                    Process.sendSignal(imppids[i], Process.SIGNAL_QUIT);
4639                    synchronized (this) {
4640                        try {
4641                            wait(200);
4642                        } catch (InterruptedException e) {
4643                        }
4644                    }
4645                }
4646                for (i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
4647                    ProcessRecord r = mLruProcesses.get(i);
4648                    boolean done = false;
4649                    for (int j=0; j<imppids.length && imppids[j] != 0; j++) {
4650                        if (imppids[j] == r.pid) {
4651                            done = true;
4652                            break;
4653                        }
4654                    }
4655                    if (!done && r.thread != null) {
4656                        Process.sendSignal(r.pid, Process.SIGNAL_QUIT);
4657                        synchronized (this) {
4658                            try {
4659                                wait(200);
4660                            } catch (InterruptedException e) {
4661                            }
4662                        }
4663                    }
4664                }
4665            }
4666        }
4667
4668        if (mController != null) {
4669            try {
4670                int res = mController.appNotResponding(app.processName,
4671                        app.pid, info.toString());
4672                if (res != 0) {
4673                    if (res < 0) {
4674                        // wait until the SIGQUIT has had a chance to process before killing the
4675                        // process.
4676                        try {
4677                            wait(2000);
4678                        } catch (InterruptedException e) {
4679                        }
4680
4681                        Process.killProcess(app.pid);
4682                        return;
4683                    }
4684                }
4685            } catch (RemoteException e) {
4686                mController = null;
4687            }
4688        }
4689
4690        makeAppNotRespondingLocked(app,
4691                activity != null ? activity.shortComponentName : null,
4692                annotation != null ? "ANR " + annotation : "ANR",
4693                info.toString());
4694        Message msg = Message.obtain();
4695        HashMap map = new HashMap();
4696        msg.what = SHOW_NOT_RESPONDING_MSG;
4697        msg.obj = map;
4698        map.put("app", app);
4699        if (activity != null) {
4700            map.put("activity", activity);
4701        }
4702
4703        mHandler.sendMessage(msg);
4704        return;
4705    }
4706
4707    /**
4708     * If a stack trace file has been configured, prepare the filesystem
4709     * by creating the directory if it doesn't exist and optionally
4710     * removing the old trace file.
4711     *
4712     * @param removeExisting If set, the existing trace file will be removed.
4713     * @return Returns true if the trace file preparations succeeded
4714     */
4715    public static boolean prepareTraceFile(boolean removeExisting) {
4716        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4717        boolean fileReady = false;
4718        if (!TextUtils.isEmpty(tracesPath)) {
4719            File f = new File(tracesPath);
4720            if (!f.exists()) {
4721                // Ensure the enclosing directory exists
4722                File dir = f.getParentFile();
4723                if (!dir.exists()) {
4724                    fileReady = dir.mkdirs();
4725                    FileUtils.setPermissions(dir.getAbsolutePath(),
4726                            FileUtils.S_IRWXU | FileUtils.S_IRWXG | FileUtils.S_IXOTH, -1, -1);
4727                } else if (dir.isDirectory()) {
4728                    fileReady = true;
4729                }
4730            } else if (removeExisting) {
4731                // Remove the previous traces file, so we don't fill the disk.
4732                // The VM will recreate it
4733                Log.i(TAG, "Removing old ANR trace file from " + tracesPath);
4734                fileReady = f.delete();
4735            }
4736
4737            if (removeExisting) {
4738                try {
4739                    f.createNewFile();
4740                    FileUtils.setPermissions(f.getAbsolutePath(),
4741                            FileUtils.S_IRWXU | FileUtils.S_IRWXG
4742                            | FileUtils.S_IWOTH | FileUtils.S_IROTH, -1, -1);
4743                    fileReady = true;
4744                } catch (IOException e) {
4745                    Log.w(TAG, "Unable to make ANR traces file", e);
4746                }
4747            }
4748        }
4749
4750        return fileReady;
4751    }
4752
4753
4754    private final void decPersistentCountLocked(ProcessRecord app)
4755    {
4756        app.persistentActivities--;
4757        if (app.persistentActivities > 0) {
4758            // Still more of 'em...
4759            return;
4760        }
4761        if (app.persistent) {
4762            // Ah, but the application itself is persistent.  Whatever!
4763            return;
4764        }
4765
4766        // App is no longer persistent...  make sure it and the ones
4767        // following it in the LRU list have the correc oom_adj.
4768        updateOomAdjLocked();
4769    }
4770
4771    public void setPersistent(IBinder token, boolean isPersistent) {
4772        if (checkCallingPermission(android.Manifest.permission.PERSISTENT_ACTIVITY)
4773                != PackageManager.PERMISSION_GRANTED) {
4774            String msg = "Permission Denial: setPersistent() from pid="
4775                    + Binder.getCallingPid()
4776                    + ", uid=" + Binder.getCallingUid()
4777                    + " requires " + android.Manifest.permission.PERSISTENT_ACTIVITY;
4778            Log.w(TAG, msg);
4779            throw new SecurityException(msg);
4780        }
4781
4782        synchronized(this) {
4783            int index = indexOfTokenLocked(token);
4784            if (index < 0) {
4785                return;
4786            }
4787            HistoryRecord r = (HistoryRecord)mHistory.get(index);
4788            ProcessRecord app = r.app;
4789
4790            if (localLOGV) Log.v(
4791                TAG, "Setting persistence " + isPersistent + ": " + r);
4792
4793            if (isPersistent) {
4794                if (r.persistent) {
4795                    // Okay okay, I heard you already!
4796                    if (localLOGV) Log.v(TAG, "Already persistent!");
4797                    return;
4798                }
4799                r.persistent = true;
4800                app.persistentActivities++;
4801                if (localLOGV) Log.v(TAG, "Num persistent now: " + app.persistentActivities);
4802                if (app.persistentActivities > 1) {
4803                    // We aren't the first...
4804                    if (localLOGV) Log.v(TAG, "Not the first!");
4805                    return;
4806                }
4807                if (app.persistent) {
4808                    // This would be redundant.
4809                    if (localLOGV) Log.v(TAG, "App is persistent!");
4810                    return;
4811                }
4812
4813                // App is now persistent...  make sure it and the ones
4814                // following it now have the correct oom_adj.
4815                final long origId = Binder.clearCallingIdentity();
4816                updateOomAdjLocked();
4817                Binder.restoreCallingIdentity(origId);
4818
4819            } else {
4820                if (!r.persistent) {
4821                    // Okay okay, I heard you already!
4822                    return;
4823                }
4824                r.persistent = false;
4825                final long origId = Binder.clearCallingIdentity();
4826                decPersistentCountLocked(app);
4827                Binder.restoreCallingIdentity(origId);
4828
4829            }
4830        }
4831    }
4832
4833    public boolean clearApplicationUserData(final String packageName,
4834            final IPackageDataObserver observer) {
4835        int uid = Binder.getCallingUid();
4836        int pid = Binder.getCallingPid();
4837        long callingId = Binder.clearCallingIdentity();
4838        try {
4839            IPackageManager pm = ActivityThread.getPackageManager();
4840            int pkgUid = -1;
4841            synchronized(this) {
4842                try {
4843                    pkgUid = pm.getPackageUid(packageName);
4844                } catch (RemoteException e) {
4845                }
4846                if (pkgUid == -1) {
4847                    Log.w(TAG, "Invalid packageName:" + packageName);
4848                    return false;
4849                }
4850                if (uid == pkgUid || checkComponentPermission(
4851                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4852                        pid, uid, -1)
4853                        == PackageManager.PERMISSION_GRANTED) {
4854                    forceStopPackageLocked(packageName, pkgUid);
4855                } else {
4856                    throw new SecurityException(pid+" does not have permission:"+
4857                            android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" +
4858                                    "for process:"+packageName);
4859                }
4860            }
4861
4862            try {
4863                //clear application user data
4864                pm.clearApplicationUserData(packageName, observer);
4865                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4866                        Uri.fromParts("package", packageName, null));
4867                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4868                broadcastIntentLocked(null, null, intent,
4869                        null, null, 0, null, null, null,
4870                        false, false, MY_PID, Process.SYSTEM_UID);
4871            } catch (RemoteException e) {
4872            }
4873        } finally {
4874            Binder.restoreCallingIdentity(callingId);
4875        }
4876        return true;
4877    }
4878
4879    public void killBackgroundProcesses(final String packageName) {
4880        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4881                != PackageManager.PERMISSION_GRANTED &&
4882                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4883                        != PackageManager.PERMISSION_GRANTED) {
4884            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4885                    + Binder.getCallingPid()
4886                    + ", uid=" + Binder.getCallingUid()
4887                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4888            Log.w(TAG, msg);
4889            throw new SecurityException(msg);
4890        }
4891
4892        long callingId = Binder.clearCallingIdentity();
4893        try {
4894            IPackageManager pm = ActivityThread.getPackageManager();
4895            int pkgUid = -1;
4896            synchronized(this) {
4897                try {
4898                    pkgUid = pm.getPackageUid(packageName);
4899                } catch (RemoteException e) {
4900                }
4901                if (pkgUid == -1) {
4902                    Log.w(TAG, "Invalid packageName: " + packageName);
4903                    return;
4904                }
4905                killPackageProcessesLocked(packageName, pkgUid,
4906                        SECONDARY_SERVER_ADJ, false);
4907            }
4908        } finally {
4909            Binder.restoreCallingIdentity(callingId);
4910        }
4911    }
4912
4913    public void forceStopPackage(final String packageName) {
4914        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4915                != PackageManager.PERMISSION_GRANTED) {
4916            String msg = "Permission Denial: forceStopPackage() from pid="
4917                    + Binder.getCallingPid()
4918                    + ", uid=" + Binder.getCallingUid()
4919                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4920            Log.w(TAG, msg);
4921            throw new SecurityException(msg);
4922        }
4923
4924        long callingId = Binder.clearCallingIdentity();
4925        try {
4926            IPackageManager pm = ActivityThread.getPackageManager();
4927            int pkgUid = -1;
4928            synchronized(this) {
4929                try {
4930                    pkgUid = pm.getPackageUid(packageName);
4931                } catch (RemoteException e) {
4932                }
4933                if (pkgUid == -1) {
4934                    Log.w(TAG, "Invalid packageName: " + packageName);
4935                    return;
4936                }
4937                forceStopPackageLocked(packageName, pkgUid);
4938            }
4939        } finally {
4940            Binder.restoreCallingIdentity(callingId);
4941        }
4942    }
4943
4944    /*
4945     * The pkg name and uid have to be specified.
4946     * @see android.app.IActivityManager#killApplicationWithUid(java.lang.String, int)
4947     */
4948    public void killApplicationWithUid(String pkg, int uid) {
4949        if (pkg == null) {
4950            return;
4951        }
4952        // Make sure the uid is valid.
4953        if (uid < 0) {
4954            Log.w(TAG, "Invalid uid specified for pkg : " + pkg);
4955            return;
4956        }
4957        int callerUid = Binder.getCallingUid();
4958        // Only the system server can kill an application
4959        if (callerUid == Process.SYSTEM_UID) {
4960            // Post an aysnc message to kill the application
4961            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4962            msg.arg1 = uid;
4963            msg.arg2 = 0;
4964            msg.obj = pkg;
4965            mHandler.sendMessage(msg);
4966        } else {
4967            throw new SecurityException(callerUid + " cannot kill pkg: " +
4968                    pkg);
4969        }
4970    }
4971
4972    public void closeSystemDialogs(String reason) {
4973        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4974        if (reason != null) {
4975            intent.putExtra("reason", reason);
4976        }
4977
4978        final int uid = Binder.getCallingUid();
4979        final long origId = Binder.clearCallingIdentity();
4980        synchronized (this) {
4981            int i = mWatchers.beginBroadcast();
4982            while (i > 0) {
4983                i--;
4984                IActivityWatcher w = mWatchers.getBroadcastItem(i);
4985                if (w != null) {
4986                    try {
4987                        w.closingSystemDialogs(reason);
4988                    } catch (RemoteException e) {
4989                    }
4990                }
4991            }
4992            mWatchers.finishBroadcast();
4993
4994            mWindowManager.closeSystemDialogs(reason);
4995
4996            for (i=mHistory.size()-1; i>=0; i--) {
4997                HistoryRecord r = (HistoryRecord)mHistory.get(i);
4998                if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
4999                    finishActivityLocked(r, i,
5000                            Activity.RESULT_CANCELED, null, "close-sys");
5001                }
5002            }
5003
5004            broadcastIntentLocked(null, null, intent, null,
5005                    null, 0, null, null, null, false, false, -1, uid);
5006        }
5007        Binder.restoreCallingIdentity(origId);
5008    }
5009
5010    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
5011            throws RemoteException {
5012        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5013        for (int i=pids.length-1; i>=0; i--) {
5014            infos[i] = new Debug.MemoryInfo();
5015            Debug.getMemoryInfo(pids[i], infos[i]);
5016        }
5017        return infos;
5018    }
5019
5020    public void killApplicationProcess(String processName, int uid) {
5021        if (processName == null) {
5022            return;
5023        }
5024
5025        int callerUid = Binder.getCallingUid();
5026        // Only the system server can kill an application
5027        if (callerUid == Process.SYSTEM_UID) {
5028            synchronized (this) {
5029                ProcessRecord app = getProcessRecordLocked(processName, uid);
5030                if (app != null) {
5031                    try {
5032                        app.thread.scheduleSuicide();
5033                    } catch (RemoteException e) {
5034                        // If the other end already died, then our work here is done.
5035                    }
5036                } else {
5037                    Log.w(TAG, "Process/uid not found attempting kill of "
5038                            + processName + " / " + uid);
5039                }
5040            }
5041        } else {
5042            throw new SecurityException(callerUid + " cannot kill app process: " +
5043                    processName);
5044        }
5045    }
5046
5047    private void forceStopPackageLocked(final String packageName, int uid) {
5048        forceStopPackageLocked(packageName, uid, false);
5049        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5050                Uri.fromParts("package", packageName, null));
5051        intent.putExtra(Intent.EXTRA_UID, uid);
5052        broadcastIntentLocked(null, null, intent,
5053                null, null, 0, null, null, null,
5054                false, false, MY_PID, Process.SYSTEM_UID);
5055    }
5056
5057    private final void killPackageProcessesLocked(String packageName, int uid,
5058            int minOomAdj, boolean callerWillRestart) {
5059        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5060
5061        // Remove all processes this package may have touched: all with the
5062        // same UID (except for the system or root user), and all whose name
5063        // matches the package name.
5064        final String procNamePrefix = packageName + ":";
5065        for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
5066            final int NA = apps.size();
5067            for (int ia=0; ia<NA; ia++) {
5068                ProcessRecord app = apps.valueAt(ia);
5069                if (app.removed) {
5070                    procs.add(app);
5071                } else if ((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid)
5072                        || app.processName.equals(packageName)
5073                        || app.processName.startsWith(procNamePrefix)) {
5074                    if (app.setAdj >= minOomAdj) {
5075                        app.removed = true;
5076                        procs.add(app);
5077                    }
5078                }
5079            }
5080        }
5081
5082        int N = procs.size();
5083        for (int i=0; i<N; i++) {
5084            removeProcessLocked(procs.get(i), callerWillRestart);
5085        }
5086    }
5087
5088    private final void forceStopPackageLocked(String name, int uid,
5089            boolean callerWillRestart) {
5090        int i, N;
5091
5092        if (uid < 0) {
5093            try {
5094                uid = ActivityThread.getPackageManager().getPackageUid(name);
5095            } catch (RemoteException e) {
5096            }
5097        }
5098
5099        Log.i(TAG, "Force stopping package " + name + " uid=" + uid);
5100
5101        Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator();
5102        while (badApps.hasNext()) {
5103            SparseArray<Long> ba = badApps.next();
5104            if (ba.get(uid) != null) {
5105                badApps.remove();
5106            }
5107        }
5108
5109        killPackageProcessesLocked(name, uid, -100, callerWillRestart);
5110
5111        for (i=mHistory.size()-1; i>=0; i--) {
5112            HistoryRecord r = (HistoryRecord)mHistory.get(i);
5113            if (r.packageName.equals(name)) {
5114                Log.i(TAG, "  Force finishing activity " + r);
5115                if (r.app != null) {
5116                    r.app.removed = true;
5117                }
5118                r.app = null;
5119                finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "uninstall");
5120            }
5121        }
5122
5123        ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
5124        for (ServiceRecord service : mServices.values()) {
5125            if (service.packageName.equals(name)) {
5126                Log.i(TAG, "  Force stopping service " + service);
5127                if (service.app != null) {
5128                    service.app.removed = true;
5129                }
5130                service.app = null;
5131                services.add(service);
5132            }
5133        }
5134
5135        N = services.size();
5136        for (i=0; i<N; i++) {
5137            bringDownServiceLocked(services.get(i), true);
5138        }
5139
5140        resumeTopActivityLocked(null);
5141    }
5142
5143    private final boolean removeProcessLocked(ProcessRecord app, boolean callerWillRestart) {
5144        final String name = app.processName;
5145        final int uid = app.info.uid;
5146        if (DEBUG_PROCESSES) Log.d(
5147            TAG, "Force removing process " + app + " (" + name
5148            + "/" + uid + ")");
5149
5150        mProcessNames.remove(name, uid);
5151        boolean needRestart = false;
5152        if (app.pid > 0 && app.pid != MY_PID) {
5153            int pid = app.pid;
5154            synchronized (mPidsSelfLocked) {
5155                mPidsSelfLocked.remove(pid);
5156                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5157            }
5158            handleAppDiedLocked(app, true);
5159            mLruProcesses.remove(app);
5160            Process.killProcess(pid);
5161
5162            if (app.persistent) {
5163                if (!callerWillRestart) {
5164                    addAppLocked(app.info);
5165                } else {
5166                    needRestart = true;
5167                }
5168            }
5169        } else {
5170            mRemovedProcesses.add(app);
5171        }
5172
5173        return needRestart;
5174    }
5175
5176    private final void processStartTimedOutLocked(ProcessRecord app) {
5177        final int pid = app.pid;
5178        boolean gone = false;
5179        synchronized (mPidsSelfLocked) {
5180            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5181            if (knownApp != null && knownApp.thread == null) {
5182                mPidsSelfLocked.remove(pid);
5183                gone = true;
5184            }
5185        }
5186
5187        if (gone) {
5188            Log.w(TAG, "Process " + app + " failed to attach");
5189            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.info.uid,
5190                    app.processName);
5191            mProcessNames.remove(app.processName, app.info.uid);
5192            // Take care of any launching providers waiting for this process.
5193            checkAppInLaunchingProvidersLocked(app, true);
5194            // Take care of any services that are waiting for the process.
5195            for (int i=0; i<mPendingServices.size(); i++) {
5196                ServiceRecord sr = mPendingServices.get(i);
5197                if (app.info.uid == sr.appInfo.uid
5198                        && app.processName.equals(sr.processName)) {
5199                    Log.w(TAG, "Forcing bringing down service: " + sr);
5200                    mPendingServices.remove(i);
5201                    i--;
5202                    bringDownServiceLocked(sr, true);
5203                }
5204            }
5205            Process.killProcess(pid);
5206            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5207                Log.w(TAG, "Unattached app died before backup, skipping");
5208                try {
5209                    IBackupManager bm = IBackupManager.Stub.asInterface(
5210                            ServiceManager.getService(Context.BACKUP_SERVICE));
5211                    bm.agentDisconnected(app.info.packageName);
5212                } catch (RemoteException e) {
5213                    // Can't happen; the backup manager is local
5214                }
5215            }
5216            if (mPendingBroadcast != null && mPendingBroadcast.curApp.pid == pid) {
5217                Log.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5218                mPendingBroadcast = null;
5219                scheduleBroadcastsLocked();
5220            }
5221        } else {
5222            Log.w(TAG, "Spurious process start timeout - pid not known for " + app);
5223        }
5224    }
5225
5226    private final boolean attachApplicationLocked(IApplicationThread thread,
5227            int pid) {
5228
5229        // Find the application record that is being attached...  either via
5230        // the pid if we are running in multiple processes, or just pull the
5231        // next app record if we are emulating process with anonymous threads.
5232        ProcessRecord app;
5233        if (pid != MY_PID && pid >= 0) {
5234            synchronized (mPidsSelfLocked) {
5235                app = mPidsSelfLocked.get(pid);
5236            }
5237        } else if (mStartingProcesses.size() > 0) {
5238            app = mStartingProcesses.remove(0);
5239            app.setPid(pid);
5240        } else {
5241            app = null;
5242        }
5243
5244        if (app == null) {
5245            Log.w(TAG, "No pending application record for pid " + pid
5246                    + " (IApplicationThread " + thread + "); dropping process");
5247            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5248            if (pid > 0 && pid != MY_PID) {
5249                Process.killProcess(pid);
5250            } else {
5251                try {
5252                    thread.scheduleExit();
5253                } catch (Exception e) {
5254                    // Ignore exceptions.
5255                }
5256            }
5257            return false;
5258        }
5259
5260        // If this application record is still attached to a previous
5261        // process, clean it up now.
5262        if (app.thread != null) {
5263            handleAppDiedLocked(app, true);
5264        }
5265
5266        // Tell the process all about itself.
5267
5268        if (localLOGV) Log.v(
5269                TAG, "Binding process pid " + pid + " to record " + app);
5270
5271        String processName = app.processName;
5272        try {
5273            thread.asBinder().linkToDeath(new AppDeathRecipient(
5274                    app, pid, thread), 0);
5275        } catch (RemoteException e) {
5276            app.resetPackageList();
5277            startProcessLocked(app, "link fail", processName);
5278            return false;
5279        }
5280
5281        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName);
5282
5283        app.thread = thread;
5284        app.curAdj = app.setAdj = -100;
5285        app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
5286        app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
5287        app.forcingToForeground = null;
5288        app.foregroundServices = false;
5289        app.debugging = false;
5290
5291        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5292
5293        boolean normalMode = mSystemReady || isAllowedWhileBooting(app.info);
5294        List providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5295
5296        if (!normalMode) {
5297            Log.i(TAG, "Launching preboot mode app: " + app);
5298        }
5299
5300        if (localLOGV) Log.v(
5301            TAG, "New app record " + app
5302            + " thread=" + thread.asBinder() + " pid=" + pid);
5303        try {
5304            int testMode = IApplicationThread.DEBUG_OFF;
5305            if (mDebugApp != null && mDebugApp.equals(processName)) {
5306                testMode = mWaitForDebugger
5307                    ? IApplicationThread.DEBUG_WAIT
5308                    : IApplicationThread.DEBUG_ON;
5309                app.debugging = true;
5310                if (mDebugTransient) {
5311                    mDebugApp = mOrigDebugApp;
5312                    mWaitForDebugger = mOrigWaitForDebugger;
5313                }
5314            }
5315
5316            // If the app is being launched for restore or full backup, set it up specially
5317            boolean isRestrictedBackupMode = false;
5318            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5319                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5320                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5321            }
5322
5323            ensurePackageDexOpt(app.instrumentationInfo != null
5324                    ? app.instrumentationInfo.packageName
5325                    : app.info.packageName);
5326            if (app.instrumentationClass != null) {
5327                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5328            }
5329            if (DEBUG_CONFIGURATION) Log.v(TAG, "Binding proc "
5330                    + processName + " with config " + mConfiguration);
5331            thread.bindApplication(processName, app.instrumentationInfo != null
5332                    ? app.instrumentationInfo : app.info, providers,
5333                    app.instrumentationClass, app.instrumentationProfileFile,
5334                    app.instrumentationArguments, app.instrumentationWatcher, testMode,
5335                    isRestrictedBackupMode || !normalMode,
5336                    mConfiguration, getCommonServicesLocked());
5337            updateLruProcessLocked(app, false, true);
5338            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5339        } catch (Exception e) {
5340            // todo: Yikes!  What should we do?  For now we will try to
5341            // start another process, but that could easily get us in
5342            // an infinite loop of restarting processes...
5343            Log.w(TAG, "Exception thrown during bind!", e);
5344
5345            app.resetPackageList();
5346            startProcessLocked(app, "bind fail", processName);
5347            return false;
5348        }
5349
5350        // Remove this record from the list of starting applications.
5351        mPersistentStartingProcesses.remove(app);
5352        mProcessesOnHold.remove(app);
5353
5354        boolean badApp = false;
5355        boolean didSomething = false;
5356
5357        // See if the top visible activity is waiting to run in this process...
5358        HistoryRecord hr = topRunningActivityLocked(null);
5359        if (hr != null) {
5360            if (hr.app == null && app.info.uid == hr.info.applicationInfo.uid
5361                    && processName.equals(hr.processName)) {
5362                try {
5363                    if (realStartActivityLocked(hr, app, true, true)) {
5364                        didSomething = true;
5365                    }
5366                } catch (Exception e) {
5367                    Log.w(TAG, "Exception in new application when starting activity "
5368                          + hr.intent.getComponent().flattenToShortString(), e);
5369                    badApp = true;
5370                }
5371            } else {
5372                ensureActivitiesVisibleLocked(hr, null, processName, 0);
5373            }
5374        }
5375
5376        // Find any services that should be running in this process...
5377        if (!badApp && mPendingServices.size() > 0) {
5378            ServiceRecord sr = null;
5379            try {
5380                for (int i=0; i<mPendingServices.size(); i++) {
5381                    sr = mPendingServices.get(i);
5382                    if (app.info.uid != sr.appInfo.uid
5383                            || !processName.equals(sr.processName)) {
5384                        continue;
5385                    }
5386
5387                    mPendingServices.remove(i);
5388                    i--;
5389                    realStartServiceLocked(sr, app);
5390                    didSomething = true;
5391                }
5392            } catch (Exception e) {
5393                Log.w(TAG, "Exception in new application when starting service "
5394                      + sr.shortName, e);
5395                badApp = true;
5396            }
5397        }
5398
5399        // Check if the next broadcast receiver is in this process...
5400        BroadcastRecord br = mPendingBroadcast;
5401        if (!badApp && br != null && br.curApp == app) {
5402            try {
5403                mPendingBroadcast = null;
5404                processCurBroadcastLocked(br, app);
5405                didSomething = true;
5406            } catch (Exception e) {
5407                Log.w(TAG, "Exception in new application when starting receiver "
5408                      + br.curComponent.flattenToShortString(), e);
5409                badApp = true;
5410                logBroadcastReceiverDiscard(br);
5411                finishReceiverLocked(br.receiver, br.resultCode, br.resultData,
5412                        br.resultExtras, br.resultAbort, true);
5413                scheduleBroadcastsLocked();
5414            }
5415        }
5416
5417        // Check whether the next backup agent is in this process...
5418        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.info.uid) {
5419            if (DEBUG_BACKUP) Log.v(TAG, "New app is backup target, launching agent for " + app);
5420            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5421            try {
5422                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, mBackupTarget.backupMode);
5423            } catch (Exception e) {
5424                Log.w(TAG, "Exception scheduling backup agent creation: ");
5425                e.printStackTrace();
5426            }
5427        }
5428
5429        if (badApp) {
5430            // todo: Also need to kill application to deal with all
5431            // kinds of exceptions.
5432            handleAppDiedLocked(app, false);
5433            return false;
5434        }
5435
5436        if (!didSomething) {
5437            updateOomAdjLocked();
5438        }
5439
5440        return true;
5441    }
5442
5443    public final void attachApplication(IApplicationThread thread) {
5444        synchronized (this) {
5445            int callingPid = Binder.getCallingPid();
5446            final long origId = Binder.clearCallingIdentity();
5447            attachApplicationLocked(thread, callingPid);
5448            Binder.restoreCallingIdentity(origId);
5449        }
5450    }
5451
5452    public final void activityIdle(IBinder token, Configuration config) {
5453        final long origId = Binder.clearCallingIdentity();
5454        activityIdleInternal(token, false, config);
5455        Binder.restoreCallingIdentity(origId);
5456    }
5457
5458    final ArrayList<HistoryRecord> processStoppingActivitiesLocked(
5459            boolean remove) {
5460        int N = mStoppingActivities.size();
5461        if (N <= 0) return null;
5462
5463        ArrayList<HistoryRecord> stops = null;
5464
5465        final boolean nowVisible = mResumedActivity != null
5466                && mResumedActivity.nowVisible
5467                && !mResumedActivity.waitingVisible;
5468        for (int i=0; i<N; i++) {
5469            HistoryRecord s = mStoppingActivities.get(i);
5470            if (localLOGV) Log.v(TAG, "Stopping " + s + ": nowVisible="
5471                    + nowVisible + " waitingVisible=" + s.waitingVisible
5472                    + " finishing=" + s.finishing);
5473            if (s.waitingVisible && nowVisible) {
5474                mWaitingVisibleActivities.remove(s);
5475                s.waitingVisible = false;
5476                if (s.finishing) {
5477                    // If this activity is finishing, it is sitting on top of
5478                    // everyone else but we now know it is no longer needed...
5479                    // so get rid of it.  Otherwise, we need to go through the
5480                    // normal flow and hide it once we determine that it is
5481                    // hidden by the activities in front of it.
5482                    if (localLOGV) Log.v(TAG, "Before stopping, can hide: " + s);
5483                    mWindowManager.setAppVisibility(s, false);
5484                }
5485            }
5486            if (!s.waitingVisible && remove) {
5487                if (localLOGV) Log.v(TAG, "Ready to stop: " + s);
5488                if (stops == null) {
5489                    stops = new ArrayList<HistoryRecord>();
5490                }
5491                stops.add(s);
5492                mStoppingActivities.remove(i);
5493                N--;
5494                i--;
5495            }
5496        }
5497
5498        return stops;
5499    }
5500
5501    void enableScreenAfterBoot() {
5502        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5503                SystemClock.uptimeMillis());
5504        mWindowManager.enableScreenAfterBoot();
5505    }
5506
5507    final void activityIdleInternal(IBinder token, boolean fromTimeout,
5508            Configuration config) {
5509        if (localLOGV) Log.v(TAG, "Activity idle: " + token);
5510
5511        ArrayList<HistoryRecord> stops = null;
5512        ArrayList<HistoryRecord> finishes = null;
5513        ArrayList<HistoryRecord> thumbnails = null;
5514        int NS = 0;
5515        int NF = 0;
5516        int NT = 0;
5517        IApplicationThread sendThumbnail = null;
5518        boolean booting = false;
5519        boolean enableScreen = false;
5520
5521        synchronized (this) {
5522            if (token != null) {
5523                mHandler.removeMessages(IDLE_TIMEOUT_MSG, token);
5524            }
5525
5526            // Get the activity record.
5527            int index = indexOfTokenLocked(token);
5528            if (index >= 0) {
5529                HistoryRecord r = (HistoryRecord)mHistory.get(index);
5530
5531                // This is a hack to semi-deal with a race condition
5532                // in the client where it can be constructed with a
5533                // newer configuration from when we asked it to launch.
5534                // We'll update with whatever configuration it now says
5535                // it used to launch.
5536                if (config != null) {
5537                    r.configuration = config;
5538                }
5539
5540                // No longer need to keep the device awake.
5541                if (mResumedActivity == r && mLaunchingActivity.isHeld()) {
5542                    mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
5543                    mLaunchingActivity.release();
5544                }
5545
5546                // We are now idle.  If someone is waiting for a thumbnail from
5547                // us, we can now deliver.
5548                r.idle = true;
5549                scheduleAppGcsLocked();
5550                if (r.thumbnailNeeded && r.app != null && r.app.thread != null) {
5551                    sendThumbnail = r.app.thread;
5552                    r.thumbnailNeeded = false;
5553                }
5554
5555                // If this activity is fullscreen, set up to hide those under it.
5556
5557                if (DEBUG_VISBILITY) Log.v(TAG, "Idle activity for " + r);
5558                ensureActivitiesVisibleLocked(null, 0);
5559
5560                //Log.i(TAG, "IDLE: mBooted=" + mBooted + ", fromTimeout=" + fromTimeout);
5561                if (!mBooted && !fromTimeout) {
5562                    mBooted = true;
5563                    enableScreen = true;
5564                }
5565            }
5566
5567            // Atomically retrieve all of the other things to do.
5568            stops = processStoppingActivitiesLocked(true);
5569            NS = stops != null ? stops.size() : 0;
5570            if ((NF=mFinishingActivities.size()) > 0) {
5571                finishes = new ArrayList<HistoryRecord>(mFinishingActivities);
5572                mFinishingActivities.clear();
5573            }
5574            if ((NT=mCancelledThumbnails.size()) > 0) {
5575                thumbnails = new ArrayList<HistoryRecord>(mCancelledThumbnails);
5576                mCancelledThumbnails.clear();
5577            }
5578
5579            booting = mBooting;
5580            mBooting = false;
5581        }
5582
5583        int i;
5584
5585        // Send thumbnail if requested.
5586        if (sendThumbnail != null) {
5587            try {
5588                sendThumbnail.requestThumbnail(token);
5589            } catch (Exception e) {
5590                Log.w(TAG, "Exception thrown when requesting thumbnail", e);
5591                sendPendingThumbnail(null, token, null, null, true);
5592            }
5593        }
5594
5595        // Stop any activities that are scheduled to do so but have been
5596        // waiting for the next one to start.
5597        for (i=0; i<NS; i++) {
5598            HistoryRecord r = (HistoryRecord)stops.get(i);
5599            synchronized (this) {
5600                if (r.finishing) {
5601                    finishCurrentActivityLocked(r, FINISH_IMMEDIATELY);
5602                } else {
5603                    stopActivityLocked(r);
5604                }
5605            }
5606        }
5607
5608        // Finish any activities that are scheduled to do so but have been
5609        // waiting for the next one to start.
5610        for (i=0; i<NF; i++) {
5611            HistoryRecord r = (HistoryRecord)finishes.get(i);
5612            synchronized (this) {
5613                destroyActivityLocked(r, true);
5614            }
5615        }
5616
5617        // Report back to any thumbnail receivers.
5618        for (i=0; i<NT; i++) {
5619            HistoryRecord r = (HistoryRecord)thumbnails.get(i);
5620            sendPendingThumbnail(r, null, null, null, true);
5621        }
5622
5623        if (booting) {
5624            finishBooting();
5625        }
5626
5627        trimApplications();
5628        //dump();
5629        //mWindowManager.dump();
5630
5631        if (enableScreen) {
5632            enableScreenAfterBoot();
5633        }
5634    }
5635
5636    final void finishBooting() {
5637        // Ensure that any processes we had put on hold are now started
5638        // up.
5639        final int NP = mProcessesOnHold.size();
5640        if (NP > 0) {
5641            ArrayList<ProcessRecord> procs =
5642                new ArrayList<ProcessRecord>(mProcessesOnHold);
5643            for (int ip=0; ip<NP; ip++) {
5644                this.startProcessLocked(procs.get(ip), "on-hold", null);
5645            }
5646        }
5647        if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
5648            // Tell anyone interested that we are done booting!
5649            synchronized (this) {
5650                broadcastIntentLocked(null, null,
5651                        new Intent(Intent.ACTION_BOOT_COMPLETED, null),
5652                        null, null, 0, null, null,
5653                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5654                        false, false, MY_PID, Process.SYSTEM_UID);
5655            }
5656        }
5657    }
5658
5659    final void ensureBootCompleted() {
5660        boolean booting;
5661        boolean enableScreen;
5662        synchronized (this) {
5663            booting = mBooting;
5664            mBooting = false;
5665            enableScreen = !mBooted;
5666            mBooted = true;
5667        }
5668
5669        if (booting) {
5670            finishBooting();
5671        }
5672
5673        if (enableScreen) {
5674            enableScreenAfterBoot();
5675        }
5676    }
5677
5678    public final void activityPaused(IBinder token, Bundle icicle) {
5679        // Refuse possible leaked file descriptors
5680        if (icicle != null && icicle.hasFileDescriptors()) {
5681            throw new IllegalArgumentException("File descriptors passed in Bundle");
5682        }
5683
5684        final long origId = Binder.clearCallingIdentity();
5685        activityPaused(token, icicle, false);
5686        Binder.restoreCallingIdentity(origId);
5687    }
5688
5689    final void activityPaused(IBinder token, Bundle icicle, boolean timeout) {
5690        if (DEBUG_PAUSE) Log.v(
5691            TAG, "Activity paused: token=" + token + ", icicle=" + icicle
5692            + ", timeout=" + timeout);
5693
5694        HistoryRecord r = null;
5695
5696        synchronized (this) {
5697            int index = indexOfTokenLocked(token);
5698            if (index >= 0) {
5699                r = (HistoryRecord)mHistory.get(index);
5700                if (!timeout) {
5701                    r.icicle = icicle;
5702                    r.haveState = true;
5703                }
5704                mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);
5705                if (mPausingActivity == r) {
5706                    r.state = ActivityState.PAUSED;
5707                    completePauseLocked();
5708                } else {
5709                	EventLog.writeEvent(EventLogTags.AM_FAILED_TO_PAUSE,
5710                	        System.identityHashCode(r), r.shortComponentName,
5711                			mPausingActivity != null
5712                			    ? mPausingActivity.shortComponentName : "(none)");
5713                }
5714            }
5715        }
5716    }
5717
5718    public final void activityStopped(IBinder token, Bitmap thumbnail,
5719            CharSequence description) {
5720        if (localLOGV) Log.v(
5721            TAG, "Activity stopped: token=" + token);
5722
5723        HistoryRecord r = null;
5724
5725        final long origId = Binder.clearCallingIdentity();
5726
5727        synchronized (this) {
5728            int index = indexOfTokenLocked(token);
5729            if (index >= 0) {
5730                r = (HistoryRecord)mHistory.get(index);
5731                r.thumbnail = thumbnail;
5732                r.description = description;
5733                r.stopped = true;
5734                r.state = ActivityState.STOPPED;
5735                if (!r.finishing) {
5736                    if (r.configDestroy) {
5737                        destroyActivityLocked(r, true);
5738                        resumeTopActivityLocked(null);
5739                    }
5740                }
5741            }
5742        }
5743
5744        if (r != null) {
5745            sendPendingThumbnail(r, null, null, null, false);
5746        }
5747
5748        trimApplications();
5749
5750        Binder.restoreCallingIdentity(origId);
5751    }
5752
5753    public final void activityDestroyed(IBinder token) {
5754        if (DEBUG_SWITCH) Log.v(TAG, "ACTIVITY DESTROYED: " + token);
5755        synchronized (this) {
5756            mHandler.removeMessages(DESTROY_TIMEOUT_MSG, token);
5757
5758            int index = indexOfTokenLocked(token);
5759            if (index >= 0) {
5760                HistoryRecord r = (HistoryRecord)mHistory.get(index);
5761                if (r.state == ActivityState.DESTROYING) {
5762                    final long origId = Binder.clearCallingIdentity();
5763                    removeActivityFromHistoryLocked(r);
5764                    Binder.restoreCallingIdentity(origId);
5765                }
5766            }
5767        }
5768    }
5769
5770    public String getCallingPackage(IBinder token) {
5771        synchronized (this) {
5772            HistoryRecord r = getCallingRecordLocked(token);
5773            return r != null && r.app != null ? r.info.packageName : null;
5774        }
5775    }
5776
5777    public ComponentName getCallingActivity(IBinder token) {
5778        synchronized (this) {
5779            HistoryRecord r = getCallingRecordLocked(token);
5780            return r != null ? r.intent.getComponent() : null;
5781        }
5782    }
5783
5784    private HistoryRecord getCallingRecordLocked(IBinder token) {
5785        int index = indexOfTokenLocked(token);
5786        if (index >= 0) {
5787            HistoryRecord r = (HistoryRecord)mHistory.get(index);
5788            if (r != null) {
5789                return r.resultTo;
5790            }
5791        }
5792        return null;
5793    }
5794
5795    public ComponentName getActivityClassForToken(IBinder token) {
5796        synchronized(this) {
5797            int index = indexOfTokenLocked(token);
5798            if (index >= 0) {
5799                HistoryRecord r = (HistoryRecord)mHistory.get(index);
5800                return r.intent.getComponent();
5801            }
5802            return null;
5803        }
5804    }
5805
5806    public String getPackageForToken(IBinder token) {
5807        synchronized(this) {
5808            int index = indexOfTokenLocked(token);
5809            if (index >= 0) {
5810                HistoryRecord r = (HistoryRecord)mHistory.get(index);
5811                return r.packageName;
5812            }
5813            return null;
5814        }
5815    }
5816
5817    public IIntentSender getIntentSender(int type,
5818            String packageName, IBinder token, String resultWho,
5819            int requestCode, Intent intent, String resolvedType, int flags) {
5820        // Refuse possible leaked file descriptors
5821        if (intent != null && intent.hasFileDescriptors() == true) {
5822            throw new IllegalArgumentException("File descriptors passed in Intent");
5823        }
5824
5825        if (type == INTENT_SENDER_BROADCAST) {
5826            if ((intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5827                throw new IllegalArgumentException(
5828                        "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5829            }
5830        }
5831
5832        synchronized(this) {
5833            int callingUid = Binder.getCallingUid();
5834            try {
5835                if (callingUid != 0 && callingUid != Process.SYSTEM_UID &&
5836                        Process.supportsProcesses()) {
5837                    int uid = ActivityThread.getPackageManager()
5838                            .getPackageUid(packageName);
5839                    if (uid != Binder.getCallingUid()) {
5840                        String msg = "Permission Denial: getIntentSender() from pid="
5841                            + Binder.getCallingPid()
5842                            + ", uid=" + Binder.getCallingUid()
5843                            + ", (need uid=" + uid + ")"
5844                            + " is not allowed to send as package " + packageName;
5845                        Log.w(TAG, msg);
5846                        throw new SecurityException(msg);
5847                    }
5848                }
5849            } catch (RemoteException e) {
5850                throw new SecurityException(e);
5851            }
5852            HistoryRecord activity = null;
5853            if (type == INTENT_SENDER_ACTIVITY_RESULT) {
5854                int index = indexOfTokenLocked(token);
5855                if (index < 0) {
5856                    return null;
5857                }
5858                activity = (HistoryRecord)mHistory.get(index);
5859                if (activity.finishing) {
5860                    return null;
5861                }
5862            }
5863
5864            final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5865            final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5866            final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5867            flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5868                    |PendingIntent.FLAG_UPDATE_CURRENT);
5869
5870            PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5871                    type, packageName, activity, resultWho,
5872                    requestCode, intent, resolvedType, flags);
5873            WeakReference<PendingIntentRecord> ref;
5874            ref = mIntentSenderRecords.get(key);
5875            PendingIntentRecord rec = ref != null ? ref.get() : null;
5876            if (rec != null) {
5877                if (!cancelCurrent) {
5878                    if (updateCurrent) {
5879                        rec.key.requestIntent.replaceExtras(intent);
5880                    }
5881                    return rec;
5882                }
5883                rec.canceled = true;
5884                mIntentSenderRecords.remove(key);
5885            }
5886            if (noCreate) {
5887                return rec;
5888            }
5889            rec = new PendingIntentRecord(this, key, callingUid);
5890            mIntentSenderRecords.put(key, rec.ref);
5891            if (type == INTENT_SENDER_ACTIVITY_RESULT) {
5892                if (activity.pendingResults == null) {
5893                    activity.pendingResults
5894                            = new HashSet<WeakReference<PendingIntentRecord>>();
5895                }
5896                activity.pendingResults.add(rec.ref);
5897            }
5898            return rec;
5899        }
5900    }
5901
5902    public void cancelIntentSender(IIntentSender sender) {
5903        if (!(sender instanceof PendingIntentRecord)) {
5904            return;
5905        }
5906        synchronized(this) {
5907            PendingIntentRecord rec = (PendingIntentRecord)sender;
5908            try {
5909                int uid = ActivityThread.getPackageManager()
5910                        .getPackageUid(rec.key.packageName);
5911                if (uid != Binder.getCallingUid()) {
5912                    String msg = "Permission Denial: cancelIntentSender() from pid="
5913                        + Binder.getCallingPid()
5914                        + ", uid=" + Binder.getCallingUid()
5915                        + " is not allowed to cancel packges "
5916                        + rec.key.packageName;
5917                    Log.w(TAG, msg);
5918                    throw new SecurityException(msg);
5919                }
5920            } catch (RemoteException e) {
5921                throw new SecurityException(e);
5922            }
5923            cancelIntentSenderLocked(rec, true);
5924        }
5925    }
5926
5927    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5928        rec.canceled = true;
5929        mIntentSenderRecords.remove(rec.key);
5930        if (cleanActivity && rec.key.activity != null) {
5931            rec.key.activity.pendingResults.remove(rec.ref);
5932        }
5933    }
5934
5935    public String getPackageForIntentSender(IIntentSender pendingResult) {
5936        if (!(pendingResult instanceof PendingIntentRecord)) {
5937            return null;
5938        }
5939        synchronized(this) {
5940            try {
5941                PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5942                return res.key.packageName;
5943            } catch (ClassCastException e) {
5944            }
5945        }
5946        return null;
5947    }
5948
5949    public void setProcessLimit(int max) {
5950        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5951                "setProcessLimit()");
5952        mProcessLimit = max;
5953    }
5954
5955    public int getProcessLimit() {
5956        return mProcessLimit;
5957    }
5958
5959    void foregroundTokenDied(ForegroundToken token) {
5960        synchronized (ActivityManagerService.this) {
5961            synchronized (mPidsSelfLocked) {
5962                ForegroundToken cur
5963                    = mForegroundProcesses.get(token.pid);
5964                if (cur != token) {
5965                    return;
5966                }
5967                mForegroundProcesses.remove(token.pid);
5968                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
5969                if (pr == null) {
5970                    return;
5971                }
5972                pr.forcingToForeground = null;
5973                pr.foregroundServices = false;
5974            }
5975            updateOomAdjLocked();
5976        }
5977    }
5978
5979    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
5980        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5981                "setProcessForeground()");
5982        synchronized(this) {
5983            boolean changed = false;
5984
5985            synchronized (mPidsSelfLocked) {
5986                ProcessRecord pr = mPidsSelfLocked.get(pid);
5987                if (pr == null) {
5988                    Log.w(TAG, "setProcessForeground called on unknown pid: " + pid);
5989                    return;
5990                }
5991                ForegroundToken oldToken = mForegroundProcesses.get(pid);
5992                if (oldToken != null) {
5993                    oldToken.token.unlinkToDeath(oldToken, 0);
5994                    mForegroundProcesses.remove(pid);
5995                    pr.forcingToForeground = null;
5996                    changed = true;
5997                }
5998                if (isForeground && token != null) {
5999                    ForegroundToken newToken = new ForegroundToken() {
6000                        public void binderDied() {
6001                            foregroundTokenDied(this);
6002                        }
6003                    };
6004                    newToken.pid = pid;
6005                    newToken.token = token;
6006                    try {
6007                        token.linkToDeath(newToken, 0);
6008                        mForegroundProcesses.put(pid, newToken);
6009                        pr.forcingToForeground = token;
6010                        changed = true;
6011                    } catch (RemoteException e) {
6012                        // If the process died while doing this, we will later
6013                        // do the cleanup with the process death link.
6014                    }
6015                }
6016            }
6017
6018            if (changed) {
6019                updateOomAdjLocked();
6020            }
6021        }
6022    }
6023
6024    // =========================================================
6025    // PERMISSIONS
6026    // =========================================================
6027
6028    static class PermissionController extends IPermissionController.Stub {
6029        ActivityManagerService mActivityManagerService;
6030        PermissionController(ActivityManagerService activityManagerService) {
6031            mActivityManagerService = activityManagerService;
6032        }
6033
6034        public boolean checkPermission(String permission, int pid, int uid) {
6035            return mActivityManagerService.checkPermission(permission, pid,
6036                    uid) == PackageManager.PERMISSION_GRANTED;
6037        }
6038    }
6039
6040    /**
6041     * This can be called with or without the global lock held.
6042     */
6043    int checkComponentPermission(String permission, int pid, int uid,
6044            int reqUid) {
6045        // We might be performing an operation on behalf of an indirect binder
6046        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6047        // client identity accordingly before proceeding.
6048        Identity tlsIdentity = sCallerIdentity.get();
6049        if (tlsIdentity != null) {
6050            Log.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6051                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6052            uid = tlsIdentity.uid;
6053            pid = tlsIdentity.pid;
6054        }
6055
6056        // Root, system server and our own process get to do everything.
6057        if (uid == 0 || uid == Process.SYSTEM_UID || pid == MY_PID ||
6058            !Process.supportsProcesses()) {
6059            return PackageManager.PERMISSION_GRANTED;
6060        }
6061        // If the target requires a specific UID, always fail for others.
6062        if (reqUid >= 0 && uid != reqUid) {
6063            Log.w(TAG, "Permission denied: checkComponentPermission() reqUid=" + reqUid);
6064            return PackageManager.PERMISSION_DENIED;
6065        }
6066        if (permission == null) {
6067            return PackageManager.PERMISSION_GRANTED;
6068        }
6069        try {
6070            return ActivityThread.getPackageManager()
6071                    .checkUidPermission(permission, uid);
6072        } catch (RemoteException e) {
6073            // Should never happen, but if it does... deny!
6074            Log.e(TAG, "PackageManager is dead?!?", e);
6075        }
6076        return PackageManager.PERMISSION_DENIED;
6077    }
6078
6079    /**
6080     * As the only public entry point for permissions checking, this method
6081     * can enforce the semantic that requesting a check on a null global
6082     * permission is automatically denied.  (Internally a null permission
6083     * string is used when calling {@link #checkComponentPermission} in cases
6084     * when only uid-based security is needed.)
6085     *
6086     * This can be called with or without the global lock held.
6087     */
6088    public int checkPermission(String permission, int pid, int uid) {
6089        if (permission == null) {
6090            return PackageManager.PERMISSION_DENIED;
6091        }
6092        return checkComponentPermission(permission, pid, uid, -1);
6093    }
6094
6095    /**
6096     * Binder IPC calls go through the public entry point.
6097     * This can be called with or without the global lock held.
6098     */
6099    int checkCallingPermission(String permission) {
6100        return checkPermission(permission,
6101                Binder.getCallingPid(),
6102                Binder.getCallingUid());
6103    }
6104
6105    /**
6106     * This can be called with or without the global lock held.
6107     */
6108    void enforceCallingPermission(String permission, String func) {
6109        if (checkCallingPermission(permission)
6110                == PackageManager.PERMISSION_GRANTED) {
6111            return;
6112        }
6113
6114        String msg = "Permission Denial: " + func + " from pid="
6115                + Binder.getCallingPid()
6116                + ", uid=" + Binder.getCallingUid()
6117                + " requires " + permission;
6118        Log.w(TAG, msg);
6119        throw new SecurityException(msg);
6120    }
6121
6122    private final boolean checkHoldingPermissionsLocked(IPackageManager pm,
6123            ProviderInfo pi, int uid, int modeFlags) {
6124        try {
6125            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6126                if ((pi.readPermission != null) &&
6127                        (pm.checkUidPermission(pi.readPermission, uid)
6128                                != PackageManager.PERMISSION_GRANTED)) {
6129                    return false;
6130                }
6131            }
6132            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6133                if ((pi.writePermission != null) &&
6134                        (pm.checkUidPermission(pi.writePermission, uid)
6135                                != PackageManager.PERMISSION_GRANTED)) {
6136                    return false;
6137                }
6138            }
6139            return true;
6140        } catch (RemoteException e) {
6141            return false;
6142        }
6143    }
6144
6145    private final boolean checkUriPermissionLocked(Uri uri, int uid,
6146            int modeFlags) {
6147        // Root gets to do everything.
6148        if (uid == 0 || !Process.supportsProcesses()) {
6149            return true;
6150        }
6151        HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6152        if (perms == null) return false;
6153        UriPermission perm = perms.get(uri);
6154        if (perm == null) return false;
6155        return (modeFlags&perm.modeFlags) == modeFlags;
6156    }
6157
6158    public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
6159        // Another redirected-binder-call permissions check as in
6160        // {@link checkComponentPermission}.
6161        Identity tlsIdentity = sCallerIdentity.get();
6162        if (tlsIdentity != null) {
6163            uid = tlsIdentity.uid;
6164            pid = tlsIdentity.pid;
6165        }
6166
6167        // Our own process gets to do everything.
6168        if (pid == MY_PID) {
6169            return PackageManager.PERMISSION_GRANTED;
6170        }
6171        synchronized(this) {
6172            return checkUriPermissionLocked(uri, uid, modeFlags)
6173                    ? PackageManager.PERMISSION_GRANTED
6174                    : PackageManager.PERMISSION_DENIED;
6175        }
6176    }
6177
6178    private void grantUriPermissionLocked(int callingUid,
6179            String targetPkg, Uri uri, int modeFlags, HistoryRecord activity) {
6180        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
6181                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6182        if (modeFlags == 0) {
6183            return;
6184        }
6185
6186        final IPackageManager pm = ActivityThread.getPackageManager();
6187
6188        // If this is not a content: uri, we can't do anything with it.
6189        if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
6190            return;
6191        }
6192
6193        String name = uri.getAuthority();
6194        ProviderInfo pi = null;
6195        ContentProviderRecord cpr
6196                = (ContentProviderRecord)mProvidersByName.get(name);
6197        if (cpr != null) {
6198            pi = cpr.info;
6199        } else {
6200            try {
6201                pi = pm.resolveContentProvider(name,
6202                        PackageManager.GET_URI_PERMISSION_PATTERNS);
6203            } catch (RemoteException ex) {
6204            }
6205        }
6206        if (pi == null) {
6207            Log.w(TAG, "No content provider found for: " + name);
6208            return;
6209        }
6210
6211        int targetUid;
6212        try {
6213            targetUid = pm.getPackageUid(targetPkg);
6214            if (targetUid < 0) {
6215                return;
6216            }
6217        } catch (RemoteException ex) {
6218            return;
6219        }
6220
6221        // First...  does the target actually need this permission?
6222        if (checkHoldingPermissionsLocked(pm, pi, targetUid, modeFlags)) {
6223            // No need to grant the target this permission.
6224            return;
6225        }
6226
6227        // Second...  maybe someone else has already granted the
6228        // permission?
6229        if (checkUriPermissionLocked(uri, targetUid, modeFlags)) {
6230            // No need to grant the target this permission.
6231            return;
6232        }
6233
6234        // Third...  is the provider allowing granting of URI permissions?
6235        if (!pi.grantUriPermissions) {
6236            throw new SecurityException("Provider " + pi.packageName
6237                    + "/" + pi.name
6238                    + " does not allow granting of Uri permissions (uri "
6239                    + uri + ")");
6240        }
6241        if (pi.uriPermissionPatterns != null) {
6242            final int N = pi.uriPermissionPatterns.length;
6243            boolean allowed = false;
6244            for (int i=0; i<N; i++) {
6245                if (pi.uriPermissionPatterns[i] != null
6246                        && pi.uriPermissionPatterns[i].match(uri.getPath())) {
6247                    allowed = true;
6248                    break;
6249                }
6250            }
6251            if (!allowed) {
6252                throw new SecurityException("Provider " + pi.packageName
6253                        + "/" + pi.name
6254                        + " does not allow granting of permission to path of Uri "
6255                        + uri);
6256            }
6257        }
6258
6259        // Fourth...  does the caller itself have permission to access
6260        // this uri?
6261        if (!checkHoldingPermissionsLocked(pm, pi, callingUid, modeFlags)) {
6262            if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6263                throw new SecurityException("Uid " + callingUid
6264                        + " does not have permission to uri " + uri);
6265            }
6266        }
6267
6268        // Okay!  So here we are: the caller has the assumed permission
6269        // to the uri, and the target doesn't.  Let's now give this to
6270        // the target.
6271
6272        HashMap<Uri, UriPermission> targetUris
6273                = mGrantedUriPermissions.get(targetUid);
6274        if (targetUris == null) {
6275            targetUris = new HashMap<Uri, UriPermission>();
6276            mGrantedUriPermissions.put(targetUid, targetUris);
6277        }
6278
6279        UriPermission perm = targetUris.get(uri);
6280        if (perm == null) {
6281            perm = new UriPermission(targetUid, uri);
6282            targetUris.put(uri, perm);
6283
6284        }
6285        perm.modeFlags |= modeFlags;
6286        if (activity == null) {
6287            perm.globalModeFlags |= modeFlags;
6288        } else if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6289            perm.readActivities.add(activity);
6290            if (activity.readUriPermissions == null) {
6291                activity.readUriPermissions = new HashSet<UriPermission>();
6292            }
6293            activity.readUriPermissions.add(perm);
6294        } else if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6295            perm.writeActivities.add(activity);
6296            if (activity.writeUriPermissions == null) {
6297                activity.writeUriPermissions = new HashSet<UriPermission>();
6298            }
6299            activity.writeUriPermissions.add(perm);
6300        }
6301    }
6302
6303    private void grantUriPermissionFromIntentLocked(int callingUid,
6304            String targetPkg, Intent intent, HistoryRecord activity) {
6305        if (intent == null) {
6306            return;
6307        }
6308        Uri data = intent.getData();
6309        if (data == null) {
6310            return;
6311        }
6312        grantUriPermissionLocked(callingUid, targetPkg, data,
6313                intent.getFlags(), activity);
6314    }
6315
6316    public void grantUriPermission(IApplicationThread caller, String targetPkg,
6317            Uri uri, int modeFlags) {
6318        synchronized(this) {
6319            final ProcessRecord r = getRecordForAppLocked(caller);
6320            if (r == null) {
6321                throw new SecurityException("Unable to find app for caller "
6322                        + caller
6323                        + " when granting permission to uri " + uri);
6324            }
6325            if (targetPkg == null) {
6326                Log.w(TAG, "grantUriPermission: null target");
6327                return;
6328            }
6329            if (uri == null) {
6330                Log.w(TAG, "grantUriPermission: null uri");
6331                return;
6332            }
6333
6334            grantUriPermissionLocked(r.info.uid, targetPkg, uri, modeFlags,
6335                    null);
6336        }
6337    }
6338
6339    private void removeUriPermissionIfNeededLocked(UriPermission perm) {
6340        if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
6341                |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
6342            HashMap<Uri, UriPermission> perms
6343                    = mGrantedUriPermissions.get(perm.uid);
6344            if (perms != null) {
6345                perms.remove(perm.uri);
6346                if (perms.size() == 0) {
6347                    mGrantedUriPermissions.remove(perm.uid);
6348                }
6349            }
6350        }
6351    }
6352
6353    private void removeActivityUriPermissionsLocked(HistoryRecord activity) {
6354        if (activity.readUriPermissions != null) {
6355            for (UriPermission perm : activity.readUriPermissions) {
6356                perm.readActivities.remove(activity);
6357                if (perm.readActivities.size() == 0 && (perm.globalModeFlags
6358                        &Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0) {
6359                    perm.modeFlags &= ~Intent.FLAG_GRANT_READ_URI_PERMISSION;
6360                    removeUriPermissionIfNeededLocked(perm);
6361                }
6362            }
6363        }
6364        if (activity.writeUriPermissions != null) {
6365            for (UriPermission perm : activity.writeUriPermissions) {
6366                perm.writeActivities.remove(activity);
6367                if (perm.writeActivities.size() == 0 && (perm.globalModeFlags
6368                        &Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0) {
6369                    perm.modeFlags &= ~Intent.FLAG_GRANT_WRITE_URI_PERMISSION;
6370                    removeUriPermissionIfNeededLocked(perm);
6371                }
6372            }
6373        }
6374    }
6375
6376    private void revokeUriPermissionLocked(int callingUid, Uri uri,
6377            int modeFlags) {
6378        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
6379                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6380        if (modeFlags == 0) {
6381            return;
6382        }
6383
6384        final IPackageManager pm = ActivityThread.getPackageManager();
6385
6386        final String authority = uri.getAuthority();
6387        ProviderInfo pi = null;
6388        ContentProviderRecord cpr
6389                = (ContentProviderRecord)mProvidersByName.get(authority);
6390        if (cpr != null) {
6391            pi = cpr.info;
6392        } else {
6393            try {
6394                pi = pm.resolveContentProvider(authority,
6395                        PackageManager.GET_URI_PERMISSION_PATTERNS);
6396            } catch (RemoteException ex) {
6397            }
6398        }
6399        if (pi == null) {
6400            Log.w(TAG, "No content provider found for: " + authority);
6401            return;
6402        }
6403
6404        // Does the caller have this permission on the URI?
6405        if (!checkHoldingPermissionsLocked(pm, pi, callingUid, modeFlags)) {
6406            // Right now, if you are not the original owner of the permission,
6407            // you are not allowed to revoke it.
6408            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6409                throw new SecurityException("Uid " + callingUid
6410                        + " does not have permission to uri " + uri);
6411            //}
6412        }
6413
6414        // Go through all of the permissions and remove any that match.
6415        final List<String> SEGMENTS = uri.getPathSegments();
6416        if (SEGMENTS != null) {
6417            final int NS = SEGMENTS.size();
6418            int N = mGrantedUriPermissions.size();
6419            for (int i=0; i<N; i++) {
6420                HashMap<Uri, UriPermission> perms
6421                        = mGrantedUriPermissions.valueAt(i);
6422                Iterator<UriPermission> it = perms.values().iterator();
6423            toploop:
6424                while (it.hasNext()) {
6425                    UriPermission perm = it.next();
6426                    Uri targetUri = perm.uri;
6427                    if (!authority.equals(targetUri.getAuthority())) {
6428                        continue;
6429                    }
6430                    List<String> targetSegments = targetUri.getPathSegments();
6431                    if (targetSegments == null) {
6432                        continue;
6433                    }
6434                    if (targetSegments.size() < NS) {
6435                        continue;
6436                    }
6437                    for (int j=0; j<NS; j++) {
6438                        if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
6439                            continue toploop;
6440                        }
6441                    }
6442                    perm.clearModes(modeFlags);
6443                    if (perm.modeFlags == 0) {
6444                        it.remove();
6445                    }
6446                }
6447                if (perms.size() == 0) {
6448                    mGrantedUriPermissions.remove(
6449                            mGrantedUriPermissions.keyAt(i));
6450                    N--;
6451                    i--;
6452                }
6453            }
6454        }
6455    }
6456
6457    public void revokeUriPermission(IApplicationThread caller, Uri uri,
6458            int modeFlags) {
6459        synchronized(this) {
6460            final ProcessRecord r = getRecordForAppLocked(caller);
6461            if (r == null) {
6462                throw new SecurityException("Unable to find app for caller "
6463                        + caller
6464                        + " when revoking permission to uri " + uri);
6465            }
6466            if (uri == null) {
6467                Log.w(TAG, "revokeUriPermission: null uri");
6468                return;
6469            }
6470
6471            modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
6472                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6473            if (modeFlags == 0) {
6474                return;
6475            }
6476
6477            final IPackageManager pm = ActivityThread.getPackageManager();
6478
6479            final String authority = uri.getAuthority();
6480            ProviderInfo pi = null;
6481            ContentProviderRecord cpr
6482                    = (ContentProviderRecord)mProvidersByName.get(authority);
6483            if (cpr != null) {
6484                pi = cpr.info;
6485            } else {
6486                try {
6487                    pi = pm.resolveContentProvider(authority,
6488                            PackageManager.GET_URI_PERMISSION_PATTERNS);
6489                } catch (RemoteException ex) {
6490                }
6491            }
6492            if (pi == null) {
6493                Log.w(TAG, "No content provider found for: " + authority);
6494                return;
6495            }
6496
6497            revokeUriPermissionLocked(r.info.uid, uri, modeFlags);
6498        }
6499    }
6500
6501    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
6502        synchronized (this) {
6503            ProcessRecord app =
6504                who != null ? getRecordForAppLocked(who) : null;
6505            if (app == null) return;
6506
6507            Message msg = Message.obtain();
6508            msg.what = WAIT_FOR_DEBUGGER_MSG;
6509            msg.obj = app;
6510            msg.arg1 = waiting ? 1 : 0;
6511            mHandler.sendMessage(msg);
6512        }
6513    }
6514
6515    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
6516        outInfo.availMem = Process.getFreeMemory();
6517        outInfo.threshold = HOME_APP_MEM;
6518        outInfo.lowMemory = outInfo.availMem <
6519                (HOME_APP_MEM + ((HIDDEN_APP_MEM-HOME_APP_MEM)/2));
6520    }
6521
6522    // =========================================================
6523    // TASK MANAGEMENT
6524    // =========================================================
6525
6526    public List getTasks(int maxNum, int flags,
6527                         IThumbnailReceiver receiver) {
6528        ArrayList list = new ArrayList();
6529
6530        PendingThumbnailsRecord pending = null;
6531        IApplicationThread topThumbnail = null;
6532        HistoryRecord topRecord = null;
6533
6534        synchronized(this) {
6535            if (localLOGV) Log.v(
6536                TAG, "getTasks: max=" + maxNum + ", flags=" + flags
6537                + ", receiver=" + receiver);
6538
6539            if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
6540                    != PackageManager.PERMISSION_GRANTED) {
6541                if (receiver != null) {
6542                    // If the caller wants to wait for pending thumbnails,
6543                    // it ain't gonna get them.
6544                    try {
6545                        receiver.finished();
6546                    } catch (RemoteException ex) {
6547                    }
6548                }
6549                String msg = "Permission Denial: getTasks() from pid="
6550                        + Binder.getCallingPid()
6551                        + ", uid=" + Binder.getCallingUid()
6552                        + " requires " + android.Manifest.permission.GET_TASKS;
6553                Log.w(TAG, msg);
6554                throw new SecurityException(msg);
6555            }
6556
6557            int pos = mHistory.size()-1;
6558            HistoryRecord next =
6559                pos >= 0 ? (HistoryRecord)mHistory.get(pos) : null;
6560            HistoryRecord top = null;
6561            CharSequence topDescription = null;
6562            TaskRecord curTask = null;
6563            int numActivities = 0;
6564            int numRunning = 0;
6565            while (pos >= 0 && maxNum > 0) {
6566                final HistoryRecord r = next;
6567                pos--;
6568                next = pos >= 0 ? (HistoryRecord)mHistory.get(pos) : null;
6569
6570                // Initialize state for next task if needed.
6571                if (top == null ||
6572                        (top.state == ActivityState.INITIALIZING
6573                            && top.task == r.task)) {
6574                    top = r;
6575                    topDescription = r.description;
6576                    curTask = r.task;
6577                    numActivities = numRunning = 0;
6578                }
6579
6580                // Add 'r' into the current task.
6581                numActivities++;
6582                if (r.app != null && r.app.thread != null) {
6583                    numRunning++;
6584                }
6585                if (topDescription == null) {
6586                    topDescription = r.description;
6587                }
6588
6589                if (localLOGV) Log.v(
6590                    TAG, r.intent.getComponent().flattenToShortString()
6591                    + ": task=" + r.task);
6592
6593                // If the next one is a different task, generate a new
6594                // TaskInfo entry for what we have.
6595                if (next == null || next.task != curTask) {
6596                    ActivityManager.RunningTaskInfo ci
6597                            = new ActivityManager.RunningTaskInfo();
6598                    ci.id = curTask.taskId;
6599                    ci.baseActivity = r.intent.getComponent();
6600                    ci.topActivity = top.intent.getComponent();
6601                    ci.thumbnail = top.thumbnail;
6602                    ci.description = topDescription;
6603                    ci.numActivities = numActivities;
6604                    ci.numRunning = numRunning;
6605                    //System.out.println(
6606                    //    "#" + maxNum + ": " + " descr=" + ci.description);
6607                    if (ci.thumbnail == null && receiver != null) {
6608                        if (localLOGV) Log.v(
6609                            TAG, "State=" + top.state + "Idle=" + top.idle
6610                            + " app=" + top.app
6611                            + " thr=" + (top.app != null ? top.app.thread : null));
6612                        if (top.state == ActivityState.RESUMED
6613                                || top.state == ActivityState.PAUSING) {
6614                            if (top.idle && top.app != null
6615                                && top.app.thread != null) {
6616                                topRecord = top;
6617                                topThumbnail = top.app.thread;
6618                            } else {
6619                                top.thumbnailNeeded = true;
6620                            }
6621                        }
6622                        if (pending == null) {
6623                            pending = new PendingThumbnailsRecord(receiver);
6624                        }
6625                        pending.pendingRecords.add(top);
6626                    }
6627                    list.add(ci);
6628                    maxNum--;
6629                    top = null;
6630                }
6631            }
6632
6633            if (pending != null) {
6634                mPendingThumbnails.add(pending);
6635            }
6636        }
6637
6638        if (localLOGV) Log.v(TAG, "We have pending thumbnails: " + pending);
6639
6640        if (topThumbnail != null) {
6641            if (localLOGV) Log.v(TAG, "Requesting top thumbnail");
6642            try {
6643                topThumbnail.requestThumbnail(topRecord);
6644            } catch (Exception e) {
6645                Log.w(TAG, "Exception thrown when requesting thumbnail", e);
6646                sendPendingThumbnail(null, topRecord, null, null, true);
6647            }
6648        }
6649
6650        if (pending == null && receiver != null) {
6651            // In this case all thumbnails were available and the client
6652            // is being asked to be told when the remaining ones come in...
6653            // which is unusually, since the top-most currently running
6654            // activity should never have a canned thumbnail!  Oh well.
6655            try {
6656                receiver.finished();
6657            } catch (RemoteException ex) {
6658            }
6659        }
6660
6661        return list;
6662    }
6663
6664    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
6665            int flags) {
6666        synchronized (this) {
6667            enforceCallingPermission(android.Manifest.permission.GET_TASKS,
6668                    "getRecentTasks()");
6669
6670            final int N = mRecentTasks.size();
6671            ArrayList<ActivityManager.RecentTaskInfo> res
6672                    = new ArrayList<ActivityManager.RecentTaskInfo>(
6673                            maxNum < N ? maxNum : N);
6674            for (int i=0; i<N && maxNum > 0; i++) {
6675                TaskRecord tr = mRecentTasks.get(i);
6676                if (((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
6677                        || (tr.intent == null)
6678                        || ((tr.intent.getFlags()
6679                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
6680                    ActivityManager.RecentTaskInfo rti
6681                            = new ActivityManager.RecentTaskInfo();
6682                    rti.id = tr.numActivities > 0 ? tr.taskId : -1;
6683                    rti.baseIntent = new Intent(
6684                            tr.intent != null ? tr.intent : tr.affinityIntent);
6685                    rti.origActivity = tr.origActivity;
6686                    res.add(rti);
6687                    maxNum--;
6688                }
6689            }
6690            return res;
6691        }
6692    }
6693
6694    private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
6695        int j;
6696        TaskRecord startTask = ((HistoryRecord)mHistory.get(startIndex)).task;
6697        TaskRecord jt = startTask;
6698
6699        // First look backwards
6700        for (j=startIndex-1; j>=0; j--) {
6701            HistoryRecord r = (HistoryRecord)mHistory.get(j);
6702            if (r.task != jt) {
6703                jt = r.task;
6704                if (affinity.equals(jt.affinity)) {
6705                    return j;
6706                }
6707            }
6708        }
6709
6710        // Now look forwards
6711        final int N = mHistory.size();
6712        jt = startTask;
6713        for (j=startIndex+1; j<N; j++) {
6714            HistoryRecord r = (HistoryRecord)mHistory.get(j);
6715            if (r.task != jt) {
6716                if (affinity.equals(jt.affinity)) {
6717                    return j;
6718                }
6719                jt = r.task;
6720            }
6721        }
6722
6723        // Might it be at the top?
6724        if (affinity.equals(((HistoryRecord)mHistory.get(N-1)).task.affinity)) {
6725            return N-1;
6726        }
6727
6728        return -1;
6729    }
6730
6731    /**
6732     * Perform a reset of the given task, if needed as part of launching it.
6733     * Returns the new HistoryRecord at the top of the task.
6734     */
6735    private final HistoryRecord resetTaskIfNeededLocked(HistoryRecord taskTop,
6736            HistoryRecord newActivity) {
6737        boolean forceReset = (newActivity.info.flags
6738                &ActivityInfo.FLAG_CLEAR_TASK_ON_LAUNCH) != 0;
6739        if (taskTop.task.getInactiveDuration() > ACTIVITY_INACTIVE_RESET_TIME) {
6740            if ((newActivity.info.flags
6741                    &ActivityInfo.FLAG_ALWAYS_RETAIN_TASK_STATE) == 0) {
6742                forceReset = true;
6743            }
6744        }
6745
6746        final TaskRecord task = taskTop.task;
6747
6748        // We are going to move through the history list so that we can look
6749        // at each activity 'target' with 'below' either the interesting
6750        // activity immediately below it in the stack or null.
6751        HistoryRecord target = null;
6752        int targetI = 0;
6753        int taskTopI = -1;
6754        int replyChainEnd = -1;
6755        int lastReparentPos = -1;
6756        for (int i=mHistory.size()-1; i>=-1; i--) {
6757            HistoryRecord below = i >= 0 ? (HistoryRecord)mHistory.get(i) : null;
6758
6759            if (below != null && below.finishing) {
6760                continue;
6761            }
6762            if (target == null) {
6763                target = below;
6764                targetI = i;
6765                // If we were in the middle of a reply chain before this
6766                // task, it doesn't appear like the root of the chain wants
6767                // anything interesting, so drop it.
6768                replyChainEnd = -1;
6769                continue;
6770            }
6771
6772            final int flags = target.info.flags;
6773
6774            final boolean finishOnTaskLaunch =
6775                (flags&ActivityInfo.FLAG_FINISH_ON_TASK_LAUNCH) != 0;
6776            final boolean allowTaskReparenting =
6777                (flags&ActivityInfo.FLAG_ALLOW_TASK_REPARENTING) != 0;
6778
6779            if (target.task == task) {
6780                // We are inside of the task being reset...  we'll either
6781                // finish this activity, push it out for another task,
6782                // or leave it as-is.  We only do this
6783                // for activities that are not the root of the task (since
6784                // if we finish the root, we may no longer have the task!).
6785                if (taskTopI < 0) {
6786                    taskTopI = targetI;
6787                }
6788                if (below != null && below.task == task) {
6789                    final boolean clearWhenTaskReset =
6790                            (target.intent.getFlags()
6791                                    &Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0;
6792                    if (!finishOnTaskLaunch && !clearWhenTaskReset && target.resultTo != null) {
6793                        // If this activity is sending a reply to a previous
6794                        // activity, we can't do anything with it now until
6795                        // we reach the start of the reply chain.
6796                        // XXX note that we are assuming the result is always
6797                        // to the previous activity, which is almost always
6798                        // the case but we really shouldn't count on.
6799                        if (replyChainEnd < 0) {
6800                            replyChainEnd = targetI;
6801                        }
6802                    } else if (!finishOnTaskLaunch && !clearWhenTaskReset && allowTaskReparenting
6803                            && target.taskAffinity != null
6804                            && !target.taskAffinity.equals(task.affinity)) {
6805                        // If this activity has an affinity for another
6806                        // task, then we need to move it out of here.  We will
6807                        // move it as far out of the way as possible, to the
6808                        // bottom of the activity stack.  This also keeps it
6809                        // correctly ordered with any activities we previously
6810                        // moved.
6811                        HistoryRecord p = (HistoryRecord)mHistory.get(0);
6812                        if (target.taskAffinity != null
6813                                && target.taskAffinity.equals(p.task.affinity)) {
6814                            // If the activity currently at the bottom has the
6815                            // same task affinity as the one we are moving,
6816                            // then merge it into the same task.
6817                            target.task = p.task;
6818                            if (DEBUG_TASKS) Log.v(TAG, "Start pushing activity " + target
6819                                    + " out to bottom task " + p.task);
6820                        } else {
6821                            mCurTask++;
6822                            if (mCurTask <= 0) {
6823                                mCurTask = 1;
6824                            }
6825                            target.task = new TaskRecord(mCurTask, target.info, null,
6826                                    (target.info.flags&ActivityInfo.FLAG_CLEAR_TASK_ON_LAUNCH) != 0);
6827                            target.task.affinityIntent = target.intent;
6828                            if (DEBUG_TASKS) Log.v(TAG, "Start pushing activity " + target
6829                                    + " out to new task " + target.task);
6830                        }
6831                        mWindowManager.setAppGroupId(target, task.taskId);
6832                        if (replyChainEnd < 0) {
6833                            replyChainEnd = targetI;
6834                        }
6835                        int dstPos = 0;
6836                        for (int srcPos=targetI; srcPos<=replyChainEnd; srcPos++) {
6837                            p = (HistoryRecord)mHistory.get(srcPos);
6838                            if (p.finishing) {
6839                                continue;
6840                            }
6841                            if (DEBUG_TASKS) Log.v(TAG, "Pushing next activity " + p
6842                                    + " out to target's task " + target.task);
6843                            task.numActivities--;
6844                            p.task = target.task;
6845                            target.task.numActivities++;
6846                            mHistory.remove(srcPos);
6847                            mHistory.add(dstPos, p);
6848                            mWindowManager.moveAppToken(dstPos, p);
6849                            mWindowManager.setAppGroupId(p, p.task.taskId);
6850                            dstPos++;
6851                            if (VALIDATE_TOKENS) {
6852                                mWindowManager.validateAppTokens(mHistory);
6853                            }
6854                            i++;
6855                        }
6856                        if (taskTop == p) {
6857                            taskTop = below;
6858                        }
6859                        if (taskTopI == replyChainEnd) {
6860                            taskTopI = -1;
6861                        }
6862                        replyChainEnd = -1;
6863                        addRecentTask(target.task);
6864                    } else if (forceReset || finishOnTaskLaunch
6865                            || clearWhenTaskReset) {
6866                        // If the activity should just be removed -- either
6867                        // because it asks for it, or the task should be
6868                        // cleared -- then finish it and anything that is
6869                        // part of its reply chain.
6870                        if (clearWhenTaskReset) {
6871                            // In this case, we want to finish this activity
6872                            // and everything above it, so be sneaky and pretend
6873                            // like these are all in the reply chain.
6874                            replyChainEnd = targetI+1;
6875                            while (replyChainEnd < mHistory.size() &&
6876                                    ((HistoryRecord)mHistory.get(
6877                                                replyChainEnd)).task == task) {
6878                                replyChainEnd++;
6879                            }
6880                            replyChainEnd--;
6881                        } else if (replyChainEnd < 0) {
6882                            replyChainEnd = targetI;
6883                        }
6884                        HistoryRecord p = null;
6885                        for (int srcPos=targetI; srcPos<=replyChainEnd; srcPos++) {
6886                            p = (HistoryRecord)mHistory.get(srcPos);
6887                            if (p.finishing) {
6888                                continue;
6889                            }
6890                            if (finishActivityLocked(p, srcPos,
6891                                    Activity.RESULT_CANCELED, null, "reset")) {
6892                                replyChainEnd--;
6893                                srcPos--;
6894                            }
6895                        }
6896                        if (taskTop == p) {
6897                            taskTop = below;
6898                        }
6899                        if (taskTopI == replyChainEnd) {
6900                            taskTopI = -1;
6901                        }
6902                        replyChainEnd = -1;
6903                    } else {
6904                        // If we were in the middle of a chain, well the
6905                        // activity that started it all doesn't want anything
6906                        // special, so leave it all as-is.
6907                        replyChainEnd = -1;
6908                    }
6909                } else {
6910                    // Reached the bottom of the task -- any reply chain
6911                    // should be left as-is.
6912                    replyChainEnd = -1;
6913                }
6914
6915            } else if (target.resultTo != null) {
6916                // If this activity is sending a reply to a previous
6917                // activity, we can't do anything with it now until
6918                // we reach the start of the reply chain.
6919                // XXX note that we are assuming the result is always
6920                // to the previous activity, which is almost always
6921                // the case but we really shouldn't count on.
6922                if (replyChainEnd < 0) {
6923                    replyChainEnd = targetI;
6924                }
6925
6926            } else if (taskTopI >= 0 && allowTaskReparenting
6927                    && task.affinity != null
6928                    && task.affinity.equals(target.taskAffinity)) {
6929                // We are inside of another task...  if this activity has
6930                // an affinity for our task, then either remove it if we are
6931                // clearing or move it over to our task.  Note that
6932                // we currently punt on the case where we are resetting a
6933                // task that is not at the top but who has activities above
6934                // with an affinity to it...  this is really not a normal
6935                // case, and we will need to later pull that task to the front
6936                // and usually at that point we will do the reset and pick
6937                // up those remaining activities.  (This only happens if
6938                // someone starts an activity in a new task from an activity
6939                // in a task that is not currently on top.)
6940                if (forceReset || finishOnTaskLaunch) {
6941                    if (replyChainEnd < 0) {
6942                        replyChainEnd = targetI;
6943                    }
6944                    HistoryRecord p = null;
6945                    for (int srcPos=targetI; srcPos<=replyChainEnd; srcPos++) {
6946                        p = (HistoryRecord)mHistory.get(srcPos);
6947                        if (p.finishing) {
6948                            continue;
6949                        }
6950                        if (finishActivityLocked(p, srcPos,
6951                                Activity.RESULT_CANCELED, null, "reset")) {
6952                            taskTopI--;
6953                            lastReparentPos--;
6954                            replyChainEnd--;
6955                            srcPos--;
6956                        }
6957                    }
6958                    replyChainEnd = -1;
6959                } else {
6960                    if (replyChainEnd < 0) {
6961                        replyChainEnd = targetI;
6962                    }
6963                    for (int srcPos=replyChainEnd; srcPos>=targetI; srcPos--) {
6964                        HistoryRecord p = (HistoryRecord)mHistory.get(srcPos);
6965                        if (p.finishing) {
6966                            continue;
6967                        }
6968                        if (lastReparentPos < 0) {
6969                            lastReparentPos = taskTopI;
6970                            taskTop = p;
6971                        } else {
6972                            lastReparentPos--;
6973                        }
6974                        mHistory.remove(srcPos);
6975                        p.task.numActivities--;
6976                        p.task = task;
6977                        mHistory.add(lastReparentPos, p);
6978                        if (DEBUG_TASKS) Log.v(TAG, "Pulling activity " + p
6979                                + " in to resetting task " + task);
6980                        task.numActivities++;
6981                        mWindowManager.moveAppToken(lastReparentPos, p);
6982                        mWindowManager.setAppGroupId(p, p.task.taskId);
6983                        if (VALIDATE_TOKENS) {
6984                            mWindowManager.validateAppTokens(mHistory);
6985                        }
6986                    }
6987                    replyChainEnd = -1;
6988
6989                    // Now we've moved it in to place...  but what if this is
6990                    // a singleTop activity and we have put it on top of another
6991                    // instance of the same activity?  Then we drop the instance
6992                    // below so it remains singleTop.
6993                    if (target.info.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP) {
6994                        for (int j=lastReparentPos-1; j>=0; j--) {
6995                            HistoryRecord p = (HistoryRecord)mHistory.get(j);
6996                            if (p.finishing) {
6997                                continue;
6998                            }
6999                            if (p.intent.getComponent().equals(target.intent.getComponent())) {
7000                                if (finishActivityLocked(p, j,
7001                                        Activity.RESULT_CANCELED, null, "replace")) {
7002                                    taskTopI--;
7003                                    lastReparentPos--;
7004                                }
7005                            }
7006                        }
7007                    }
7008                }
7009            }
7010
7011            target = below;
7012            targetI = i;
7013        }
7014
7015        return taskTop;
7016    }
7017
7018    /**
7019     * TODO: Add mController hook
7020     */
7021    public void moveTaskToFront(int task) {
7022        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7023                "moveTaskToFront()");
7024
7025        synchronized(this) {
7026            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7027                    Binder.getCallingUid(), "Task to front")) {
7028                return;
7029            }
7030            final long origId = Binder.clearCallingIdentity();
7031            try {
7032                int N = mRecentTasks.size();
7033                for (int i=0; i<N; i++) {
7034                    TaskRecord tr = mRecentTasks.get(i);
7035                    if (tr.taskId == task) {
7036                        moveTaskToFrontLocked(tr, null);
7037                        return;
7038                    }
7039                }
7040                for (int i=mHistory.size()-1; i>=0; i--) {
7041                    HistoryRecord hr = (HistoryRecord)mHistory.get(i);
7042                    if (hr.task.taskId == task) {
7043                        moveTaskToFrontLocked(hr.task, null);
7044                        return;
7045                    }
7046                }
7047            } finally {
7048                Binder.restoreCallingIdentity(origId);
7049            }
7050        }
7051    }
7052
7053    private final void moveTaskToFrontLocked(TaskRecord tr, HistoryRecord reason) {
7054        if (DEBUG_SWITCH) Log.v(TAG, "moveTaskToFront: " + tr);
7055
7056        final int task = tr.taskId;
7057        int top = mHistory.size()-1;
7058
7059        if (top < 0 || ((HistoryRecord)mHistory.get(top)).task.taskId == task) {
7060            // nothing to do!
7061            return;
7062        }
7063
7064        ArrayList moved = new ArrayList();
7065
7066        // Applying the affinities may have removed entries from the history,
7067        // so get the size again.
7068        top = mHistory.size()-1;
7069        int pos = top;
7070
7071        // Shift all activities with this task up to the top
7072        // of the stack, keeping them in the same internal order.
7073        while (pos >= 0) {
7074            HistoryRecord r = (HistoryRecord)mHistory.get(pos);
7075            if (localLOGV) Log.v(
7076                TAG, "At " + pos + " ckp " + r.task + ": " + r);
7077            boolean first = true;
7078            if (r.task.taskId == task) {
7079                if (localLOGV) Log.v(TAG, "Removing and adding at " + top);
7080                mHistory.remove(pos);
7081                mHistory.add(top, r);
7082                moved.add(0, r);
7083                top--;
7084                if (first) {
7085                    addRecentTask(r.task);
7086                    first = false;
7087                }
7088            }
7089            pos--;
7090        }
7091
7092        if (DEBUG_TRANSITION) Log.v(TAG,
7093                "Prepare to front transition: task=" + tr);
7094        if (reason != null &&
7095                (reason.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) {
7096            mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_NONE);
7097            HistoryRecord r = topRunningActivityLocked(null);
7098            if (r != null) {
7099                mNoAnimActivities.add(r);
7100            }
7101        } else {
7102            mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_TASK_TO_FRONT);
7103        }
7104
7105        mWindowManager.moveAppTokensToTop(moved);
7106        if (VALIDATE_TOKENS) {
7107            mWindowManager.validateAppTokens(mHistory);
7108        }
7109
7110        finishTaskMove(task);
7111        EventLog.writeEvent(EventLogTags.AM_TASK_TO_FRONT, task);
7112    }
7113
7114    private final void finishTaskMove(int task) {
7115        resumeTopActivityLocked(null);
7116    }
7117
7118    public void moveTaskToBack(int task) {
7119        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7120                "moveTaskToBack()");
7121
7122        synchronized(this) {
7123            if (mResumedActivity != null && mResumedActivity.task.taskId == task) {
7124                if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7125                        Binder.getCallingUid(), "Task to back")) {
7126                    return;
7127                }
7128            }
7129            final long origId = Binder.clearCallingIdentity();
7130            moveTaskToBackLocked(task, null);
7131            Binder.restoreCallingIdentity(origId);
7132        }
7133    }
7134
7135    /**
7136     * Moves an activity, and all of the other activities within the same task, to the bottom
7137     * of the history stack.  The activity's order within the task is unchanged.
7138     *
7139     * @param token A reference to the activity we wish to move
7140     * @param nonRoot If false then this only works if the activity is the root
7141     *                of a task; if true it will work for any activity in a task.
7142     * @return Returns true if the move completed, false if not.
7143     */
7144    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7145        synchronized(this) {
7146            final long origId = Binder.clearCallingIdentity();
7147            int taskId = getTaskForActivityLocked(token, !nonRoot);
7148            if (taskId >= 0) {
7149                return moveTaskToBackLocked(taskId, null);
7150            }
7151            Binder.restoreCallingIdentity(origId);
7152        }
7153        return false;
7154    }
7155
7156    /**
7157     * Worker method for rearranging history stack.  Implements the function of moving all
7158     * activities for a specific task (gathering them if disjoint) into a single group at the
7159     * bottom of the stack.
7160     *
7161     * If a watcher is installed, the action is preflighted and the watcher has an opportunity
7162     * to premeptively cancel the move.
7163     *
7164     * @param task The taskId to collect and move to the bottom.
7165     * @return Returns true if the move completed, false if not.
7166     */
7167    private final boolean moveTaskToBackLocked(int task, HistoryRecord reason) {
7168        Log.i(TAG, "moveTaskToBack: " + task);
7169
7170        // If we have a watcher, preflight the move before committing to it.  First check
7171        // for *other* available tasks, but if none are available, then try again allowing the
7172        // current task to be selected.
7173        if (mController != null) {
7174            HistoryRecord next = topRunningActivityLocked(null, task);
7175            if (next == null) {
7176                next = topRunningActivityLocked(null, 0);
7177            }
7178            if (next != null) {
7179                // ask watcher if this is allowed
7180                boolean moveOK = true;
7181                try {
7182                    moveOK = mController.activityResuming(next.packageName);
7183                } catch (RemoteException e) {
7184                    mController = null;
7185                }
7186                if (!moveOK) {
7187                    return false;
7188                }
7189            }
7190        }
7191
7192        ArrayList moved = new ArrayList();
7193
7194        if (DEBUG_TRANSITION) Log.v(TAG,
7195                "Prepare to back transition: task=" + task);
7196
7197        final int N = mHistory.size();
7198        int bottom = 0;
7199        int pos = 0;
7200
7201        // Shift all activities with this task down to the bottom
7202        // of the stack, keeping them in the same internal order.
7203        while (pos < N) {
7204            HistoryRecord r = (HistoryRecord)mHistory.get(pos);
7205            if (localLOGV) Log.v(
7206                TAG, "At " + pos + " ckp " + r.task + ": " + r);
7207            if (r.task.taskId == task) {
7208                if (localLOGV) Log.v(TAG, "Removing and adding at " + (N-1));
7209                mHistory.remove(pos);
7210                mHistory.add(bottom, r);
7211                moved.add(r);
7212                bottom++;
7213            }
7214            pos++;
7215        }
7216
7217        if (reason != null &&
7218                (reason.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) {
7219            mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_NONE);
7220            HistoryRecord r = topRunningActivityLocked(null);
7221            if (r != null) {
7222                mNoAnimActivities.add(r);
7223            }
7224        } else {
7225            mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_TASK_TO_BACK);
7226        }
7227        mWindowManager.moveAppTokensToBottom(moved);
7228        if (VALIDATE_TOKENS) {
7229            mWindowManager.validateAppTokens(mHistory);
7230        }
7231
7232        finishTaskMove(task);
7233        return true;
7234    }
7235
7236    public void moveTaskBackwards(int task) {
7237        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7238                "moveTaskBackwards()");
7239
7240        synchronized(this) {
7241            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7242                    Binder.getCallingUid(), "Task backwards")) {
7243                return;
7244            }
7245            final long origId = Binder.clearCallingIdentity();
7246            moveTaskBackwardsLocked(task);
7247            Binder.restoreCallingIdentity(origId);
7248        }
7249    }
7250
7251    private final void moveTaskBackwardsLocked(int task) {
7252        Log.e(TAG, "moveTaskBackwards not yet implemented!");
7253    }
7254
7255    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7256        synchronized(this) {
7257            return getTaskForActivityLocked(token, onlyRoot);
7258        }
7259    }
7260
7261    int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
7262        final int N = mHistory.size();
7263        TaskRecord lastTask = null;
7264        for (int i=0; i<N; i++) {
7265            HistoryRecord r = (HistoryRecord)mHistory.get(i);
7266            if (r == token) {
7267                if (!onlyRoot || lastTask != r.task) {
7268                    return r.task.taskId;
7269                }
7270                return -1;
7271            }
7272            lastTask = r.task;
7273        }
7274
7275        return -1;
7276    }
7277
7278    /**
7279     * Returns the top activity in any existing task matching the given
7280     * Intent.  Returns null if no such task is found.
7281     */
7282    private HistoryRecord findTaskLocked(Intent intent, ActivityInfo info) {
7283        ComponentName cls = intent.getComponent();
7284        if (info.targetActivity != null) {
7285            cls = new ComponentName(info.packageName, info.targetActivity);
7286        }
7287
7288        TaskRecord cp = null;
7289
7290        final int N = mHistory.size();
7291        for (int i=(N-1); i>=0; i--) {
7292            HistoryRecord r = (HistoryRecord)mHistory.get(i);
7293            if (!r.finishing && r.task != cp
7294                    && r.launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
7295                cp = r.task;
7296                //Log.i(TAG, "Comparing existing cls=" + r.task.intent.getComponent().flattenToShortString()
7297                //        + "/aff=" + r.task.affinity + " to new cls="
7298                //        + intent.getComponent().flattenToShortString() + "/aff=" + taskAffinity);
7299                if (r.task.affinity != null) {
7300                    if (r.task.affinity.equals(info.taskAffinity)) {
7301                        //Log.i(TAG, "Found matching affinity!");
7302                        return r;
7303                    }
7304                } else if (r.task.intent != null
7305                        && r.task.intent.getComponent().equals(cls)) {
7306                    //Log.i(TAG, "Found matching class!");
7307                    //dump();
7308                    //Log.i(TAG, "For Intent " + intent + " bringing to top: " + r.intent);
7309                    return r;
7310                } else if (r.task.affinityIntent != null
7311                        && r.task.affinityIntent.getComponent().equals(cls)) {
7312                    //Log.i(TAG, "Found matching class!");
7313                    //dump();
7314                    //Log.i(TAG, "For Intent " + intent + " bringing to top: " + r.intent);
7315                    return r;
7316                }
7317            }
7318        }
7319
7320        return null;
7321    }
7322
7323    /**
7324     * Returns the first activity (starting from the top of the stack) that
7325     * is the same as the given activity.  Returns null if no such activity
7326     * is found.
7327     */
7328    private HistoryRecord findActivityLocked(Intent intent, ActivityInfo info) {
7329        ComponentName cls = intent.getComponent();
7330        if (info.targetActivity != null) {
7331            cls = new ComponentName(info.packageName, info.targetActivity);
7332        }
7333
7334        final int N = mHistory.size();
7335        for (int i=(N-1); i>=0; i--) {
7336            HistoryRecord r = (HistoryRecord)mHistory.get(i);
7337            if (!r.finishing) {
7338                if (r.intent.getComponent().equals(cls)) {
7339                    //Log.i(TAG, "Found matching class!");
7340                    //dump();
7341                    //Log.i(TAG, "For Intent " + intent + " bringing to top: " + r.intent);
7342                    return r;
7343                }
7344            }
7345        }
7346
7347        return null;
7348    }
7349
7350    public void finishOtherInstances(IBinder token, ComponentName className) {
7351        synchronized(this) {
7352            final long origId = Binder.clearCallingIdentity();
7353
7354            int N = mHistory.size();
7355            TaskRecord lastTask = null;
7356            for (int i=0; i<N; i++) {
7357                HistoryRecord r = (HistoryRecord)mHistory.get(i);
7358                if (r.realActivity.equals(className)
7359                        && r != token && lastTask != r.task) {
7360                    if (finishActivityLocked(r, i, Activity.RESULT_CANCELED,
7361                            null, "others")) {
7362                        i--;
7363                        N--;
7364                    }
7365                }
7366                lastTask = r.task;
7367            }
7368
7369            Binder.restoreCallingIdentity(origId);
7370        }
7371    }
7372
7373    // =========================================================
7374    // THUMBNAILS
7375    // =========================================================
7376
7377    public void reportThumbnail(IBinder token,
7378            Bitmap thumbnail, CharSequence description) {
7379        //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
7380        final long origId = Binder.clearCallingIdentity();
7381        sendPendingThumbnail(null, token, thumbnail, description, true);
7382        Binder.restoreCallingIdentity(origId);
7383    }
7384
7385    final void sendPendingThumbnail(HistoryRecord r, IBinder token,
7386            Bitmap thumbnail, CharSequence description, boolean always) {
7387        TaskRecord task = null;
7388        ArrayList receivers = null;
7389
7390        //System.out.println("Send pending thumbnail: " + r);
7391
7392        synchronized(this) {
7393            if (r == null) {
7394                int index = indexOfTokenLocked(token);
7395                if (index < 0) {
7396                    return;
7397                }
7398                r = (HistoryRecord)mHistory.get(index);
7399            }
7400            if (thumbnail == null) {
7401                thumbnail = r.thumbnail;
7402                description = r.description;
7403            }
7404            if (thumbnail == null && !always) {
7405                // If there is no thumbnail, and this entry is not actually
7406                // going away, then abort for now and pick up the next
7407                // thumbnail we get.
7408                return;
7409            }
7410            task = r.task;
7411
7412            int N = mPendingThumbnails.size();
7413            int i=0;
7414            while (i<N) {
7415                PendingThumbnailsRecord pr =
7416                    (PendingThumbnailsRecord)mPendingThumbnails.get(i);
7417                //System.out.println("Looking in " + pr.pendingRecords);
7418                if (pr.pendingRecords.remove(r)) {
7419                    if (receivers == null) {
7420                        receivers = new ArrayList();
7421                    }
7422                    receivers.add(pr);
7423                    if (pr.pendingRecords.size() == 0) {
7424                        pr.finished = true;
7425                        mPendingThumbnails.remove(i);
7426                        N--;
7427                        continue;
7428                    }
7429                }
7430                i++;
7431            }
7432        }
7433
7434        if (receivers != null) {
7435            final int N = receivers.size();
7436            for (int i=0; i<N; i++) {
7437                try {
7438                    PendingThumbnailsRecord pr =
7439                        (PendingThumbnailsRecord)receivers.get(i);
7440                    pr.receiver.newThumbnail(
7441                        task != null ? task.taskId : -1, thumbnail, description);
7442                    if (pr.finished) {
7443                        pr.receiver.finished();
7444                    }
7445                } catch (Exception e) {
7446                    Log.w(TAG, "Exception thrown when sending thumbnail", e);
7447                }
7448            }
7449        }
7450    }
7451
7452    // =========================================================
7453    // CONTENT PROVIDERS
7454    // =========================================================
7455
7456    private final List generateApplicationProvidersLocked(ProcessRecord app) {
7457        List providers = null;
7458        try {
7459            providers = ActivityThread.getPackageManager().
7460                queryContentProviders(app.processName, app.info.uid,
7461                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
7462        } catch (RemoteException ex) {
7463        }
7464        if (providers != null) {
7465            final int N = providers.size();
7466            for (int i=0; i<N; i++) {
7467                ProviderInfo cpi =
7468                    (ProviderInfo)providers.get(i);
7469                ContentProviderRecord cpr =
7470                    (ContentProviderRecord)mProvidersByClass.get(cpi.name);
7471                if (cpr == null) {
7472                    cpr = new ContentProviderRecord(cpi, app.info);
7473                    mProvidersByClass.put(cpi.name, cpr);
7474                }
7475                app.pubProviders.put(cpi.name, cpr);
7476                app.addPackage(cpi.applicationInfo.packageName);
7477                ensurePackageDexOpt(cpi.applicationInfo.packageName);
7478            }
7479        }
7480        return providers;
7481    }
7482
7483    private final String checkContentProviderPermissionLocked(
7484            ProviderInfo cpi, ProcessRecord r, int mode) {
7485        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
7486        final int callingUid = (r != null) ? r.info.uid : Binder.getCallingUid();
7487        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
7488                cpi.exported ? -1 : cpi.applicationInfo.uid)
7489                == PackageManager.PERMISSION_GRANTED
7490                && mode == ParcelFileDescriptor.MODE_READ_ONLY || mode == -1) {
7491            return null;
7492        }
7493        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
7494                cpi.exported ? -1 : cpi.applicationInfo.uid)
7495                == PackageManager.PERMISSION_GRANTED) {
7496            return null;
7497        }
7498
7499        PathPermission[] pps = cpi.pathPermissions;
7500        if (pps != null) {
7501            int i = pps.length;
7502            while (i > 0) {
7503                i--;
7504                PathPermission pp = pps[i];
7505                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
7506                        cpi.exported ? -1 : cpi.applicationInfo.uid)
7507                        == PackageManager.PERMISSION_GRANTED
7508                        && mode == ParcelFileDescriptor.MODE_READ_ONLY || mode == -1) {
7509                    return null;
7510                }
7511                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
7512                        cpi.exported ? -1 : cpi.applicationInfo.uid)
7513                        == PackageManager.PERMISSION_GRANTED) {
7514                    return null;
7515                }
7516            }
7517        }
7518
7519        String msg = "Permission Denial: opening provider " + cpi.name
7520                + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7521                + ", uid=" + callingUid + ") requires "
7522                + cpi.readPermission + " or " + cpi.writePermission;
7523        Log.w(TAG, msg);
7524        return msg;
7525    }
7526
7527    private final ContentProviderHolder getContentProviderImpl(
7528        IApplicationThread caller, String name) {
7529        ContentProviderRecord cpr;
7530        ProviderInfo cpi = null;
7531
7532        synchronized(this) {
7533            ProcessRecord r = null;
7534            if (caller != null) {
7535                r = getRecordForAppLocked(caller);
7536                if (r == null) {
7537                    throw new SecurityException(
7538                            "Unable to find app for caller " + caller
7539                          + " (pid=" + Binder.getCallingPid()
7540                          + ") when getting content provider " + name);
7541                }
7542            }
7543
7544            // First check if this content provider has been published...
7545            cpr = (ContentProviderRecord)mProvidersByName.get(name);
7546            if (cpr != null) {
7547                cpi = cpr.info;
7548                if (checkContentProviderPermissionLocked(cpi, r, -1) != null) {
7549                    return new ContentProviderHolder(cpi,
7550                            cpi.readPermission != null
7551                                    ? cpi.readPermission : cpi.writePermission);
7552                }
7553
7554                if (r != null && cpr.canRunHere(r)) {
7555                    // This provider has been published or is in the process
7556                    // of being published...  but it is also allowed to run
7557                    // in the caller's process, so don't make a connection
7558                    // and just let the caller instantiate its own instance.
7559                    if (cpr.provider != null) {
7560                        // don't give caller the provider object, it needs
7561                        // to make its own.
7562                        cpr = new ContentProviderRecord(cpr);
7563                    }
7564                    return cpr;
7565                }
7566
7567                final long origId = Binder.clearCallingIdentity();
7568
7569                // In this case the provider instance already exists, so we can
7570                // return it right away.
7571                if (r != null) {
7572                    if (DEBUG_PROVIDER) Log.v(TAG,
7573                            "Adding provider requested by "
7574                            + r.processName + " from process "
7575                            + cpr.info.processName);
7576                    Integer cnt = r.conProviders.get(cpr);
7577                    if (cnt == null) {
7578                        r.conProviders.put(cpr, new Integer(1));
7579                    } else {
7580                        r.conProviders.put(cpr, new Integer(cnt.intValue()+1));
7581                    }
7582                    cpr.clients.add(r);
7583                } else {
7584                    cpr.externals++;
7585                }
7586
7587                if (cpr.app != null) {
7588                    updateOomAdjLocked(cpr.app);
7589                }
7590
7591                Binder.restoreCallingIdentity(origId);
7592
7593            } else {
7594                try {
7595                    cpi = ActivityThread.getPackageManager().
7596                        resolveContentProvider(name,
7597                                STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
7598                } catch (RemoteException ex) {
7599                }
7600                if (cpi == null) {
7601                    return null;
7602                }
7603
7604                if (checkContentProviderPermissionLocked(cpi, r, -1) != null) {
7605                    return new ContentProviderHolder(cpi,
7606                            cpi.readPermission != null
7607                                    ? cpi.readPermission : cpi.writePermission);
7608                }
7609
7610                cpr = (ContentProviderRecord)mProvidersByClass.get(cpi.name);
7611                final boolean firstClass = cpr == null;
7612                if (firstClass) {
7613                    try {
7614                        ApplicationInfo ai =
7615                            ActivityThread.getPackageManager().
7616                                getApplicationInfo(
7617                                        cpi.applicationInfo.packageName,
7618                                        STOCK_PM_FLAGS);
7619                        if (ai == null) {
7620                            Log.w(TAG, "No package info for content provider "
7621                                    + cpi.name);
7622                            return null;
7623                        }
7624                        cpr = new ContentProviderRecord(cpi, ai);
7625                    } catch (RemoteException ex) {
7626                        // pm is in same process, this will never happen.
7627                    }
7628                }
7629
7630                if (r != null && cpr.canRunHere(r)) {
7631                    // If this is a multiprocess provider, then just return its
7632                    // info and allow the caller to instantiate it.  Only do
7633                    // this if the provider is the same user as the caller's
7634                    // process, or can run as root (so can be in any process).
7635                    return cpr;
7636                }
7637
7638                if (DEBUG_PROVIDER) {
7639                    RuntimeException e = new RuntimeException("here");
7640                    Log.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.info.uid
7641                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
7642                }
7643
7644                // This is single process, and our app is now connecting to it.
7645                // See if we are already in the process of launching this
7646                // provider.
7647                final int N = mLaunchingProviders.size();
7648                int i;
7649                for (i=0; i<N; i++) {
7650                    if (mLaunchingProviders.get(i) == cpr) {
7651                        break;
7652                    }
7653                }
7654
7655                // If the provider is not already being launched, then get it
7656                // started.
7657                if (i >= N) {
7658                    final long origId = Binder.clearCallingIdentity();
7659                    ProcessRecord proc = startProcessLocked(cpi.processName,
7660                            cpr.appInfo, false, 0, "content provider",
7661                            new ComponentName(cpi.applicationInfo.packageName,
7662                                    cpi.name), false);
7663                    if (proc == null) {
7664                        Log.w(TAG, "Unable to launch app "
7665                                + cpi.applicationInfo.packageName + "/"
7666                                + cpi.applicationInfo.uid + " for provider "
7667                                + name + ": process is bad");
7668                        return null;
7669                    }
7670                    cpr.launchingApp = proc;
7671                    mLaunchingProviders.add(cpr);
7672                    Binder.restoreCallingIdentity(origId);
7673                }
7674
7675                // Make sure the provider is published (the same provider class
7676                // may be published under multiple names).
7677                if (firstClass) {
7678                    mProvidersByClass.put(cpi.name, cpr);
7679                }
7680                mProvidersByName.put(name, cpr);
7681
7682                if (r != null) {
7683                    if (DEBUG_PROVIDER) Log.v(TAG,
7684                            "Adding provider requested by "
7685                            + r.processName + " from process "
7686                            + cpr.info.processName);
7687                    Integer cnt = r.conProviders.get(cpr);
7688                    if (cnt == null) {
7689                        r.conProviders.put(cpr, new Integer(1));
7690                    } else {
7691                        r.conProviders.put(cpr, new Integer(cnt.intValue()+1));
7692                    }
7693                    cpr.clients.add(r);
7694                } else {
7695                    cpr.externals++;
7696                }
7697            }
7698        }
7699
7700        // Wait for the provider to be published...
7701        synchronized (cpr) {
7702            while (cpr.provider == null) {
7703                if (cpr.launchingApp == null) {
7704                    Log.w(TAG, "Unable to launch app "
7705                            + cpi.applicationInfo.packageName + "/"
7706                            + cpi.applicationInfo.uid + " for provider "
7707                            + name + ": launching app became null");
7708                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
7709                            cpi.applicationInfo.packageName,
7710                            cpi.applicationInfo.uid, name);
7711                    return null;
7712                }
7713                try {
7714                    cpr.wait();
7715                } catch (InterruptedException ex) {
7716                }
7717            }
7718        }
7719        return cpr;
7720    }
7721
7722    public final ContentProviderHolder getContentProvider(
7723            IApplicationThread caller, String name) {
7724        if (caller == null) {
7725            String msg = "null IApplicationThread when getting content provider "
7726                    + name;
7727            Log.w(TAG, msg);
7728            throw new SecurityException(msg);
7729        }
7730
7731        return getContentProviderImpl(caller, name);
7732    }
7733
7734    private ContentProviderHolder getContentProviderExternal(String name) {
7735        return getContentProviderImpl(null, name);
7736    }
7737
7738    /**
7739     * Drop a content provider from a ProcessRecord's bookkeeping
7740     * @param cpr
7741     */
7742    public void removeContentProvider(IApplicationThread caller, String name) {
7743        synchronized (this) {
7744            ContentProviderRecord cpr = (ContentProviderRecord)mProvidersByName.get(name);
7745            if(cpr == null) {
7746                // remove from mProvidersByClass
7747                if (DEBUG_PROVIDER) Log.v(TAG, name +
7748                        " provider not found in providers list");
7749                return;
7750            }
7751            final ProcessRecord r = getRecordForAppLocked(caller);
7752            if (r == null) {
7753                throw new SecurityException(
7754                        "Unable to find app for caller " + caller +
7755                        " when removing content provider " + name);
7756            }
7757            //update content provider record entry info
7758            ContentProviderRecord localCpr = (ContentProviderRecord)
7759                    mProvidersByClass.get(cpr.info.name);
7760            if (DEBUG_PROVIDER) Log.v(TAG, "Removing provider requested by "
7761                    + r.info.processName + " from process "
7762                    + localCpr.appInfo.processName);
7763            if (localCpr.app == r) {
7764                //should not happen. taken care of as a local provider
7765                Log.w(TAG, "removeContentProvider called on local provider: "
7766                        + cpr.info.name + " in process " + r.processName);
7767                return;
7768            } else {
7769                Integer cnt = r.conProviders.get(localCpr);
7770                if (cnt == null || cnt.intValue() <= 1) {
7771                    localCpr.clients.remove(r);
7772                    r.conProviders.remove(localCpr);
7773                } else {
7774                    r.conProviders.put(localCpr, new Integer(cnt.intValue()-1));
7775                }
7776            }
7777            updateOomAdjLocked();
7778        }
7779    }
7780
7781    private void removeContentProviderExternal(String name) {
7782        synchronized (this) {
7783            ContentProviderRecord cpr = (ContentProviderRecord)mProvidersByName.get(name);
7784            if(cpr == null) {
7785                //remove from mProvidersByClass
7786                if(localLOGV) Log.v(TAG, name+" content provider not found in providers list");
7787                return;
7788            }
7789
7790            //update content provider record entry info
7791            ContentProviderRecord localCpr = (ContentProviderRecord) mProvidersByClass.get(cpr.info.name);
7792            localCpr.externals--;
7793            if (localCpr.externals < 0) {
7794                Log.e(TAG, "Externals < 0 for content provider " + localCpr);
7795            }
7796            updateOomAdjLocked();
7797        }
7798    }
7799
7800    public final void publishContentProviders(IApplicationThread caller,
7801            List<ContentProviderHolder> providers) {
7802        if (providers == null) {
7803            return;
7804        }
7805
7806        synchronized(this) {
7807            final ProcessRecord r = getRecordForAppLocked(caller);
7808            if (r == null) {
7809                throw new SecurityException(
7810                        "Unable to find app for caller " + caller
7811                      + " (pid=" + Binder.getCallingPid()
7812                      + ") when publishing content providers");
7813            }
7814
7815            final long origId = Binder.clearCallingIdentity();
7816
7817            final int N = providers.size();
7818            for (int i=0; i<N; i++) {
7819                ContentProviderHolder src = providers.get(i);
7820                if (src == null || src.info == null || src.provider == null) {
7821                    continue;
7822                }
7823                ContentProviderRecord dst =
7824                    (ContentProviderRecord)r.pubProviders.get(src.info.name);
7825                if (dst != null) {
7826                    mProvidersByClass.put(dst.info.name, dst);
7827                    String names[] = dst.info.authority.split(";");
7828                    for (int j = 0; j < names.length; j++) {
7829                        mProvidersByName.put(names[j], dst);
7830                    }
7831
7832                    int NL = mLaunchingProviders.size();
7833                    int j;
7834                    for (j=0; j<NL; j++) {
7835                        if (mLaunchingProviders.get(j) == dst) {
7836                            mLaunchingProviders.remove(j);
7837                            j--;
7838                            NL--;
7839                        }
7840                    }
7841                    synchronized (dst) {
7842                        dst.provider = src.provider;
7843                        dst.app = r;
7844                        dst.notifyAll();
7845                    }
7846                    updateOomAdjLocked(r);
7847                }
7848            }
7849
7850            Binder.restoreCallingIdentity(origId);
7851        }
7852    }
7853
7854    public static final void installSystemProviders() {
7855        ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
7856        List providers = mSelf.generateApplicationProvidersLocked(app);
7857        mSystemThread.installSystemProviders(providers);
7858    }
7859
7860    // =========================================================
7861    // GLOBAL MANAGEMENT
7862    // =========================================================
7863
7864    final ProcessRecord newProcessRecordLocked(IApplicationThread thread,
7865            ApplicationInfo info, String customProcess) {
7866        String proc = customProcess != null ? customProcess : info.processName;
7867        BatteryStatsImpl.Uid.Proc ps = null;
7868        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
7869        synchronized (stats) {
7870            ps = stats.getProcessStatsLocked(info.uid, proc);
7871        }
7872        return new ProcessRecord(ps, thread, info, proc);
7873    }
7874
7875    final ProcessRecord addAppLocked(ApplicationInfo info) {
7876        ProcessRecord app = getProcessRecordLocked(info.processName, info.uid);
7877
7878        if (app == null) {
7879            app = newProcessRecordLocked(null, info, null);
7880            mProcessNames.put(info.processName, info.uid, app);
7881            updateLruProcessLocked(app, true, true);
7882        }
7883
7884        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
7885                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
7886            app.persistent = true;
7887            app.maxAdj = CORE_SERVER_ADJ;
7888        }
7889        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
7890            mPersistentStartingProcesses.add(app);
7891            startProcessLocked(app, "added application", app.processName);
7892        }
7893
7894        return app;
7895    }
7896
7897    public void unhandledBack() {
7898        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
7899                "unhandledBack()");
7900
7901        synchronized(this) {
7902            int count = mHistory.size();
7903            if (DEBUG_SWITCH) Log.d(
7904                TAG, "Performing unhandledBack(): stack size = " + count);
7905            if (count > 1) {
7906                final long origId = Binder.clearCallingIdentity();
7907                finishActivityLocked((HistoryRecord)mHistory.get(count-1),
7908                        count-1, Activity.RESULT_CANCELED, null, "unhandled-back");
7909                Binder.restoreCallingIdentity(origId);
7910            }
7911        }
7912    }
7913
7914    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
7915        String name = uri.getAuthority();
7916        ContentProviderHolder cph = getContentProviderExternal(name);
7917        ParcelFileDescriptor pfd = null;
7918        if (cph != null) {
7919            // We record the binder invoker's uid in thread-local storage before
7920            // going to the content provider to open the file.  Later, in the code
7921            // that handles all permissions checks, we look for this uid and use
7922            // that rather than the Activity Manager's own uid.  The effect is that
7923            // we do the check against the caller's permissions even though it looks
7924            // to the content provider like the Activity Manager itself is making
7925            // the request.
7926            sCallerIdentity.set(new Identity(
7927                    Binder.getCallingPid(), Binder.getCallingUid()));
7928            try {
7929                pfd = cph.provider.openFile(uri, "r");
7930            } catch (FileNotFoundException e) {
7931                // do nothing; pfd will be returned null
7932            } finally {
7933                // Ensure that whatever happens, we clean up the identity state
7934                sCallerIdentity.remove();
7935            }
7936
7937            // We've got the fd now, so we're done with the provider.
7938            removeContentProviderExternal(name);
7939        } else {
7940            Log.d(TAG, "Failed to get provider for authority '" + name + "'");
7941        }
7942        return pfd;
7943    }
7944
7945    public void goingToSleep() {
7946        synchronized(this) {
7947            mSleeping = true;
7948            mWindowManager.setEventDispatching(false);
7949
7950            if (mResumedActivity != null) {
7951                pauseIfSleepingLocked();
7952            } else {
7953                Log.w(TAG, "goingToSleep with no resumed activity!");
7954            }
7955        }
7956    }
7957
7958    public boolean shutdown(int timeout) {
7959        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
7960                != PackageManager.PERMISSION_GRANTED) {
7961            throw new SecurityException("Requires permission "
7962                    + android.Manifest.permission.SHUTDOWN);
7963        }
7964
7965        boolean timedout = false;
7966
7967        synchronized(this) {
7968            mShuttingDown = true;
7969            mWindowManager.setEventDispatching(false);
7970
7971            if (mResumedActivity != null) {
7972                pauseIfSleepingLocked();
7973                final long endTime = System.currentTimeMillis() + timeout;
7974                while (mResumedActivity != null || mPausingActivity != null) {
7975                    long delay = endTime - System.currentTimeMillis();
7976                    if (delay <= 0) {
7977                        Log.w(TAG, "Activity manager shutdown timed out");
7978                        timedout = true;
7979                        break;
7980                    }
7981                    try {
7982                        this.wait();
7983                    } catch (InterruptedException e) {
7984                    }
7985                }
7986            }
7987        }
7988
7989        mUsageStatsService.shutdown();
7990        mBatteryStatsService.shutdown();
7991
7992        return timedout;
7993    }
7994
7995    void pauseIfSleepingLocked() {
7996        if (mSleeping || mShuttingDown) {
7997            if (!mGoingToSleep.isHeld()) {
7998                mGoingToSleep.acquire();
7999                if (mLaunchingActivity.isHeld()) {
8000                    mLaunchingActivity.release();
8001                    mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
8002                }
8003            }
8004
8005            // If we are not currently pausing an activity, get the current
8006            // one to pause.  If we are pausing one, we will just let that stuff
8007            // run and release the wake lock when all done.
8008            if (mPausingActivity == null) {
8009                if (DEBUG_PAUSE) Log.v(TAG, "Sleep needs to pause...");
8010                if (DEBUG_USER_LEAVING) Log.v(TAG, "Sleep => pause with userLeaving=false");
8011                startPausingLocked(false, true);
8012            }
8013        }
8014    }
8015
8016    public void wakingUp() {
8017        synchronized(this) {
8018            if (mGoingToSleep.isHeld()) {
8019                mGoingToSleep.release();
8020            }
8021            mWindowManager.setEventDispatching(true);
8022            mSleeping = false;
8023            resumeTopActivityLocked(null);
8024        }
8025    }
8026
8027    public void stopAppSwitches() {
8028        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8029                != PackageManager.PERMISSION_GRANTED) {
8030            throw new SecurityException("Requires permission "
8031                    + android.Manifest.permission.STOP_APP_SWITCHES);
8032        }
8033
8034        synchronized(this) {
8035            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
8036                    + APP_SWITCH_DELAY_TIME;
8037            mDidAppSwitch = false;
8038            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8039            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8040            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
8041        }
8042    }
8043
8044    public void resumeAppSwitches() {
8045        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8046                != PackageManager.PERMISSION_GRANTED) {
8047            throw new SecurityException("Requires permission "
8048                    + android.Manifest.permission.STOP_APP_SWITCHES);
8049        }
8050
8051        synchronized(this) {
8052            // Note that we don't execute any pending app switches... we will
8053            // let those wait until either the timeout, or the next start
8054            // activity request.
8055            mAppSwitchesAllowedTime = 0;
8056        }
8057    }
8058
8059    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
8060            String name) {
8061        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
8062            return true;
8063        }
8064
8065        final int perm = checkComponentPermission(
8066                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
8067                callingUid, -1);
8068        if (perm == PackageManager.PERMISSION_GRANTED) {
8069            return true;
8070        }
8071
8072        Log.w(TAG, name + " request from " + callingUid + " stopped");
8073        return false;
8074    }
8075
8076    public void setDebugApp(String packageName, boolean waitForDebugger,
8077            boolean persistent) {
8078        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
8079                "setDebugApp()");
8080
8081        // Note that this is not really thread safe if there are multiple
8082        // callers into it at the same time, but that's not a situation we
8083        // care about.
8084        if (persistent) {
8085            final ContentResolver resolver = mContext.getContentResolver();
8086            Settings.System.putString(
8087                resolver, Settings.System.DEBUG_APP,
8088                packageName);
8089            Settings.System.putInt(
8090                resolver, Settings.System.WAIT_FOR_DEBUGGER,
8091                waitForDebugger ? 1 : 0);
8092        }
8093
8094        synchronized (this) {
8095            if (!persistent) {
8096                mOrigDebugApp = mDebugApp;
8097                mOrigWaitForDebugger = mWaitForDebugger;
8098            }
8099            mDebugApp = packageName;
8100            mWaitForDebugger = waitForDebugger;
8101            mDebugTransient = !persistent;
8102            if (packageName != null) {
8103                final long origId = Binder.clearCallingIdentity();
8104                forceStopPackageLocked(packageName, -1, false);
8105                Binder.restoreCallingIdentity(origId);
8106            }
8107        }
8108    }
8109
8110    public void setAlwaysFinish(boolean enabled) {
8111        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
8112                "setAlwaysFinish()");
8113
8114        Settings.System.putInt(
8115                mContext.getContentResolver(),
8116                Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
8117
8118        synchronized (this) {
8119            mAlwaysFinishActivities = enabled;
8120        }
8121    }
8122
8123    public void setActivityController(IActivityController controller) {
8124        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8125                "setActivityController()");
8126        synchronized (this) {
8127            mController = controller;
8128        }
8129    }
8130
8131    public void registerActivityWatcher(IActivityWatcher watcher) {
8132        mWatchers.register(watcher);
8133    }
8134
8135    public void unregisterActivityWatcher(IActivityWatcher watcher) {
8136        mWatchers.unregister(watcher);
8137    }
8138
8139    public final void enterSafeMode() {
8140        synchronized(this) {
8141            // It only makes sense to do this before the system is ready
8142            // and started launching other packages.
8143            if (!mSystemReady) {
8144                try {
8145                    ActivityThread.getPackageManager().enterSafeMode();
8146                } catch (RemoteException e) {
8147                }
8148
8149                View v = LayoutInflater.from(mContext).inflate(
8150                        com.android.internal.R.layout.safe_mode, null);
8151                WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
8152                lp.type = WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY;
8153                lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
8154                lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
8155                lp.gravity = Gravity.BOTTOM | Gravity.LEFT;
8156                lp.format = v.getBackground().getOpacity();
8157                lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
8158                        | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
8159                ((WindowManager)mContext.getSystemService(
8160                        Context.WINDOW_SERVICE)).addView(v, lp);
8161            }
8162        }
8163    }
8164
8165    public void noteWakeupAlarm(IIntentSender sender) {
8166        if (!(sender instanceof PendingIntentRecord)) {
8167            return;
8168        }
8169        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8170        synchronized (stats) {
8171            if (mBatteryStatsService.isOnBattery()) {
8172                mBatteryStatsService.enforceCallingPermission();
8173                PendingIntentRecord rec = (PendingIntentRecord)sender;
8174                int MY_UID = Binder.getCallingUid();
8175                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
8176                BatteryStatsImpl.Uid.Pkg pkg =
8177                    stats.getPackageStatsLocked(uid, rec.key.packageName);
8178                pkg.incWakeupsLocked();
8179            }
8180        }
8181    }
8182
8183    public boolean killPidsForMemory(int[] pids) {
8184        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
8185            throw new SecurityException("killPidsForMemory only available to the system");
8186        }
8187
8188        // XXX Note: don't acquire main activity lock here, because the window
8189        // manager calls in with its locks held.
8190
8191        boolean killed = false;
8192        synchronized (mPidsSelfLocked) {
8193            int[] types = new int[pids.length];
8194            int worstType = 0;
8195            for (int i=0; i<pids.length; i++) {
8196                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
8197                if (proc != null) {
8198                    int type = proc.setAdj;
8199                    types[i] = type;
8200                    if (type > worstType) {
8201                        worstType = type;
8202                    }
8203                }
8204            }
8205
8206            // If the worse oom_adj is somewhere in the hidden proc LRU range,
8207            // then constrain it so we will kill all hidden procs.
8208            if (worstType < EMPTY_APP_ADJ && worstType > HIDDEN_APP_MIN_ADJ) {
8209                worstType = HIDDEN_APP_MIN_ADJ;
8210            }
8211            Log.w(TAG, "Killing processes for memory at adjustment " + worstType);
8212            for (int i=0; i<pids.length; i++) {
8213                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
8214                if (proc == null) {
8215                    continue;
8216                }
8217                int adj = proc.setAdj;
8218                if (adj >= worstType) {
8219                    Log.w(TAG, "Killing for memory: " + proc + " (adj "
8220                            + adj + ")");
8221                    EventLog.writeEvent(EventLogTags.AM_KILL_FOR_MEMORY, proc.pid,
8222                            proc.processName, adj);
8223                    killed = true;
8224                    Process.killProcess(pids[i]);
8225                }
8226            }
8227        }
8228        return killed;
8229    }
8230
8231    public void reportPss(IApplicationThread caller, int pss) {
8232        Watchdog.PssRequestor req;
8233        String name;
8234        ProcessRecord callerApp;
8235        synchronized (this) {
8236            if (caller == null) {
8237                return;
8238            }
8239            callerApp = getRecordForAppLocked(caller);
8240            if (callerApp == null) {
8241                return;
8242            }
8243            callerApp.lastPss = pss;
8244            req = callerApp;
8245            name = callerApp.processName;
8246        }
8247        Watchdog.getInstance().reportPss(req, name, pss);
8248        if (!callerApp.persistent) {
8249            removeRequestedPss(callerApp);
8250        }
8251    }
8252
8253    public void requestPss(Runnable completeCallback) {
8254        ArrayList<ProcessRecord> procs;
8255        synchronized (this) {
8256            mRequestPssCallback = completeCallback;
8257            mRequestPssList.clear();
8258            for (int i=mLruProcesses.size()-1; i>=0; i--) {
8259                ProcessRecord proc = mLruProcesses.get(i);
8260                if (!proc.persistent) {
8261                    mRequestPssList.add(proc);
8262                }
8263            }
8264            procs = new ArrayList<ProcessRecord>(mRequestPssList);
8265        }
8266
8267        int oldPri = Process.getThreadPriority(Process.myTid());
8268        Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
8269        for (int i=procs.size()-1; i>=0; i--) {
8270            ProcessRecord proc = procs.get(i);
8271            proc.lastPss = 0;
8272            proc.requestPss();
8273        }
8274        Process.setThreadPriority(oldPri);
8275    }
8276
8277    void removeRequestedPss(ProcessRecord proc) {
8278        Runnable callback = null;
8279        synchronized (this) {
8280            if (mRequestPssList.remove(proc)) {
8281                if (mRequestPssList.size() == 0) {
8282                    callback = mRequestPssCallback;
8283                    mRequestPssCallback = null;
8284                }
8285            }
8286        }
8287
8288        if (callback != null) {
8289            callback.run();
8290        }
8291    }
8292
8293    public void collectPss(Watchdog.PssStats stats) {
8294        stats.mEmptyPss = 0;
8295        stats.mEmptyCount = 0;
8296        stats.mBackgroundPss = 0;
8297        stats.mBackgroundCount = 0;
8298        stats.mServicePss = 0;
8299        stats.mServiceCount = 0;
8300        stats.mVisiblePss = 0;
8301        stats.mVisibleCount = 0;
8302        stats.mForegroundPss = 0;
8303        stats.mForegroundCount = 0;
8304        stats.mNoPssCount = 0;
8305        synchronized (this) {
8306            int i;
8307            int NPD = mProcDeaths.length < stats.mProcDeaths.length
8308                    ? mProcDeaths.length : stats.mProcDeaths.length;
8309            int aggr = 0;
8310            for (i=0; i<NPD; i++) {
8311                aggr += mProcDeaths[i];
8312                stats.mProcDeaths[i] = aggr;
8313            }
8314            while (i<stats.mProcDeaths.length) {
8315                stats.mProcDeaths[i] = 0;
8316                i++;
8317            }
8318
8319            for (i=mLruProcesses.size()-1; i>=0; i--) {
8320                ProcessRecord proc = mLruProcesses.get(i);
8321                if (proc.persistent) {
8322                    continue;
8323                }
8324                //Log.i(TAG, "Proc " + proc + ": pss=" + proc.lastPss);
8325                if (proc.lastPss == 0) {
8326                    stats.mNoPssCount++;
8327                    continue;
8328                }
8329                if (proc.setAdj >= HIDDEN_APP_MIN_ADJ) {
8330                    if (proc.empty) {
8331                        stats.mEmptyPss += proc.lastPss;
8332                        stats.mEmptyCount++;
8333                    } else {
8334                        stats.mBackgroundPss += proc.lastPss;
8335                        stats.mBackgroundCount++;
8336                    }
8337                } else if (proc.setAdj >= VISIBLE_APP_ADJ) {
8338                    stats.mVisiblePss += proc.lastPss;
8339                    stats.mVisibleCount++;
8340                } else {
8341                    stats.mForegroundPss += proc.lastPss;
8342                    stats.mForegroundCount++;
8343                }
8344            }
8345        }
8346    }
8347
8348    public final void startRunning(String pkg, String cls, String action,
8349            String data) {
8350        synchronized(this) {
8351            if (mStartRunning) {
8352                return;
8353            }
8354            mStartRunning = true;
8355            mTopComponent = pkg != null && cls != null
8356                    ? new ComponentName(pkg, cls) : null;
8357            mTopAction = action != null ? action : Intent.ACTION_MAIN;
8358            mTopData = data;
8359            if (!mSystemReady) {
8360                return;
8361            }
8362        }
8363
8364        systemReady(null);
8365    }
8366
8367    private void retrieveSettings() {
8368        final ContentResolver resolver = mContext.getContentResolver();
8369        String debugApp = Settings.System.getString(
8370            resolver, Settings.System.DEBUG_APP);
8371        boolean waitForDebugger = Settings.System.getInt(
8372            resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0;
8373        boolean alwaysFinishActivities = Settings.System.getInt(
8374            resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
8375
8376        Configuration configuration = new Configuration();
8377        Settings.System.getConfiguration(resolver, configuration);
8378
8379        synchronized (this) {
8380            mDebugApp = mOrigDebugApp = debugApp;
8381            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
8382            mAlwaysFinishActivities = alwaysFinishActivities;
8383            // This happens before any activities are started, so we can
8384            // change mConfiguration in-place.
8385            mConfiguration.updateFrom(configuration);
8386            if (DEBUG_CONFIGURATION) Log.v(TAG, "Initial config: " + mConfiguration);
8387        }
8388    }
8389
8390    public boolean testIsSystemReady() {
8391        // no need to synchronize(this) just to read & return the value
8392        return mSystemReady;
8393    }
8394
8395    public void systemReady(final Runnable goingCallback) {
8396        // In the simulator, startRunning will never have been called, which
8397        // normally sets a few crucial variables. Do it here instead.
8398        if (!Process.supportsProcesses()) {
8399            mStartRunning = true;
8400            mTopAction = Intent.ACTION_MAIN;
8401        }
8402
8403        synchronized(this) {
8404            if (mSystemReady) {
8405                if (goingCallback != null) goingCallback.run();
8406                return;
8407            }
8408
8409            // Check to see if there are any update receivers to run.
8410            if (!mDidUpdate) {
8411                if (mWaitingUpdate) {
8412                    return;
8413                }
8414                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
8415                List<ResolveInfo> ris = null;
8416                try {
8417                    ris = ActivityThread.getPackageManager().queryIntentReceivers(
8418                                intent, null, 0);
8419                } catch (RemoteException e) {
8420                }
8421                if (ris != null) {
8422                    for (int i=ris.size()-1; i>=0; i--) {
8423                        if ((ris.get(i).activityInfo.applicationInfo.flags
8424                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
8425                            ris.remove(i);
8426                        }
8427                    }
8428                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
8429                    for (int i=0; i<ris.size(); i++) {
8430                        ActivityInfo ai = ris.get(i).activityInfo;
8431                        intent.setComponent(new ComponentName(ai.packageName, ai.name));
8432                        IIntentReceiver finisher = null;
8433                        if (i == 0) {
8434                            finisher = new IIntentReceiver.Stub() {
8435                                public void performReceive(Intent intent, int resultCode,
8436                                        String data, Bundle extras, boolean ordered,
8437                                        boolean sticky)
8438                                        throws RemoteException {
8439                                    synchronized (ActivityManagerService.this) {
8440                                        mDidUpdate = true;
8441                                    }
8442                                    systemReady(goingCallback);
8443                                }
8444                            };
8445                        }
8446                        Log.i(TAG, "Sending system update to: " + intent.getComponent());
8447                        broadcastIntentLocked(null, null, intent, null, finisher,
8448                                0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID);
8449                        if (i == 0) {
8450                            mWaitingUpdate = true;
8451                        }
8452                    }
8453                }
8454                if (mWaitingUpdate) {
8455                    return;
8456                }
8457                mDidUpdate = true;
8458            }
8459
8460            mSystemReady = true;
8461            if (!mStartRunning) {
8462                return;
8463            }
8464        }
8465
8466        ArrayList<ProcessRecord> procsToKill = null;
8467        synchronized(mPidsSelfLocked) {
8468            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
8469                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
8470                if (!isAllowedWhileBooting(proc.info)){
8471                    if (procsToKill == null) {
8472                        procsToKill = new ArrayList<ProcessRecord>();
8473                    }
8474                    procsToKill.add(proc);
8475                }
8476            }
8477        }
8478
8479        if (procsToKill != null) {
8480            synchronized(this) {
8481                for (int i=procsToKill.size()-1; i>=0; i--) {
8482                    ProcessRecord proc = procsToKill.get(i);
8483                    Log.i(TAG, "Removing system update proc: " + proc);
8484                    removeProcessLocked(proc, true);
8485                }
8486            }
8487        }
8488
8489        Log.i(TAG, "System now ready");
8490        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
8491            SystemClock.uptimeMillis());
8492
8493        synchronized(this) {
8494            // Make sure we have no pre-ready processes sitting around.
8495
8496            if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
8497                ResolveInfo ri = mContext.getPackageManager()
8498                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
8499                                STOCK_PM_FLAGS);
8500                CharSequence errorMsg = null;
8501                if (ri != null) {
8502                    ActivityInfo ai = ri.activityInfo;
8503                    ApplicationInfo app = ai.applicationInfo;
8504                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
8505                        mTopAction = Intent.ACTION_FACTORY_TEST;
8506                        mTopData = null;
8507                        mTopComponent = new ComponentName(app.packageName,
8508                                ai.name);
8509                    } else {
8510                        errorMsg = mContext.getResources().getText(
8511                                com.android.internal.R.string.factorytest_not_system);
8512                    }
8513                } else {
8514                    errorMsg = mContext.getResources().getText(
8515                            com.android.internal.R.string.factorytest_no_action);
8516                }
8517                if (errorMsg != null) {
8518                    mTopAction = null;
8519                    mTopData = null;
8520                    mTopComponent = null;
8521                    Message msg = Message.obtain();
8522                    msg.what = SHOW_FACTORY_ERROR_MSG;
8523                    msg.getData().putCharSequence("msg", errorMsg);
8524                    mHandler.sendMessage(msg);
8525                }
8526            }
8527        }
8528
8529        retrieveSettings();
8530
8531        if (goingCallback != null) goingCallback.run();
8532
8533        synchronized (this) {
8534            if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
8535                try {
8536                    List apps = ActivityThread.getPackageManager().
8537                        getPersistentApplications(STOCK_PM_FLAGS);
8538                    if (apps != null) {
8539                        int N = apps.size();
8540                        int i;
8541                        for (i=0; i<N; i++) {
8542                            ApplicationInfo info
8543                                = (ApplicationInfo)apps.get(i);
8544                            if (info != null &&
8545                                    !info.packageName.equals("android")) {
8546                                addAppLocked(info);
8547                            }
8548                        }
8549                    }
8550                } catch (RemoteException ex) {
8551                    // pm is in same process, this will never happen.
8552                }
8553            }
8554
8555            // Start up initial activity.
8556            mBooting = true;
8557
8558            try {
8559                if (ActivityThread.getPackageManager().hasSystemUidErrors()) {
8560                    Message msg = Message.obtain();
8561                    msg.what = SHOW_UID_ERROR_MSG;
8562                    mHandler.sendMessage(msg);
8563                }
8564            } catch (RemoteException e) {
8565            }
8566
8567            resumeTopActivityLocked(null);
8568        }
8569    }
8570
8571    private boolean makeAppCrashingLocked(ProcessRecord app,
8572            String shortMsg, String longMsg, String stackTrace) {
8573        app.crashing = true;
8574        app.crashingReport = generateProcessError(app,
8575                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
8576        startAppProblemLocked(app);
8577        app.stopFreezingAllLocked();
8578        return handleAppCrashLocked(app);
8579    }
8580
8581    private ComponentName getErrorReportReceiver(ProcessRecord app) {
8582        // check if error reporting is enabled in Gservices
8583        int enabled = Settings.Gservices.getInt(mContext.getContentResolver(),
8584                Settings.Gservices.SEND_ACTION_APP_ERROR, 0);
8585        if (enabled == 0) {
8586            return null;
8587        }
8588
8589        IPackageManager pm = ActivityThread.getPackageManager();
8590
8591        try {
8592            // look for receiver in the installer package
8593            String candidate = pm.getInstallerPackageName(app.info.packageName);
8594            ComponentName result = getErrorReportReceiver(pm, app.info.packageName, candidate);
8595            if (result != null) {
8596                return result;
8597            }
8598
8599            // if the error app is on the system image, look for system apps
8600            // error receiver
8601            if ((app.info.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
8602                candidate = SystemProperties.get(SYSTEM_APPS_ERROR_RECEIVER_PROPERTY);
8603                result = getErrorReportReceiver(pm, app.info.packageName, candidate);
8604                if (result != null) {
8605                    return result;
8606                }
8607            }
8608
8609            // if there is a default receiver, try that
8610            candidate = SystemProperties.get(DEFAULT_ERROR_RECEIVER_PROPERTY);
8611            return getErrorReportReceiver(pm, app.info.packageName, candidate);
8612        } catch (RemoteException e) {
8613            // should not happen
8614            Log.e(TAG, "error talking to PackageManager", e);
8615            return null;
8616        }
8617    }
8618
8619    /**
8620     * Return activity in receiverPackage that handles ACTION_APP_ERROR.
8621     *
8622     * @param pm PackageManager isntance
8623     * @param errorPackage package which caused the error
8624     * @param receiverPackage candidate package to receive the error
8625     * @return activity component within receiverPackage which handles
8626     * ACTION_APP_ERROR, or null if not found
8627     */
8628    private ComponentName getErrorReportReceiver(IPackageManager pm, String errorPackage,
8629            String receiverPackage) throws RemoteException {
8630        if (receiverPackage == null || receiverPackage.length() == 0) {
8631            return null;
8632        }
8633
8634        // break the loop if it's the error report receiver package that crashed
8635        if (receiverPackage.equals(errorPackage)) {
8636            return null;
8637        }
8638
8639        Intent intent = new Intent(Intent.ACTION_APP_ERROR);
8640        intent.setPackage(receiverPackage);
8641        ResolveInfo info = pm.resolveIntent(intent, null, 0);
8642        if (info == null || info.activityInfo == null) {
8643            return null;
8644        }
8645        return new ComponentName(receiverPackage, info.activityInfo.name);
8646    }
8647
8648    private void makeAppNotRespondingLocked(ProcessRecord app,
8649            String activity, String shortMsg, String longMsg) {
8650        app.notResponding = true;
8651        app.notRespondingReport = generateProcessError(app,
8652                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
8653                activity, shortMsg, longMsg, null);
8654        startAppProblemLocked(app);
8655        app.stopFreezingAllLocked();
8656    }
8657
8658    /**
8659     * Generate a process error record, suitable for attachment to a ProcessRecord.
8660     *
8661     * @param app The ProcessRecord in which the error occurred.
8662     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
8663     *                      ActivityManager.AppErrorStateInfo
8664     * @param activity The activity associated with the crash, if known.
8665     * @param shortMsg Short message describing the crash.
8666     * @param longMsg Long message describing the crash.
8667     * @param stackTrace Full crash stack trace, may be null.
8668     *
8669     * @return Returns a fully-formed AppErrorStateInfo record.
8670     */
8671    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
8672            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
8673        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
8674
8675        report.condition = condition;
8676        report.processName = app.processName;
8677        report.pid = app.pid;
8678        report.uid = app.info.uid;
8679        report.tag = activity;
8680        report.shortMsg = shortMsg;
8681        report.longMsg = longMsg;
8682        report.stackTrace = stackTrace;
8683
8684        return report;
8685    }
8686
8687    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog,
8688            boolean crashed) {
8689        synchronized (this) {
8690            app.crashing = false;
8691            app.crashingReport = null;
8692            app.notResponding = false;
8693            app.notRespondingReport = null;
8694            if (app.anrDialog == fromDialog) {
8695                app.anrDialog = null;
8696            }
8697            if (app.waitDialog == fromDialog) {
8698                app.waitDialog = null;
8699            }
8700            if (app.pid > 0 && app.pid != MY_PID) {
8701                if (crashed) {
8702                    handleAppCrashLocked(app);
8703                }
8704                Log.i(ActivityManagerService.TAG, "Killing process "
8705                        + app.processName
8706                        + " (pid=" + app.pid + ") at user's request");
8707                Process.killProcess(app.pid);
8708            }
8709
8710        }
8711    }
8712
8713    private boolean handleAppCrashLocked(ProcessRecord app) {
8714        long now = SystemClock.uptimeMillis();
8715
8716        Long crashTime = mProcessCrashTimes.get(app.info.processName,
8717                app.info.uid);
8718        if (crashTime != null && now < crashTime+MIN_CRASH_INTERVAL) {
8719            // This process loses!
8720            Log.w(TAG, "Process " + app.info.processName
8721                    + " has crashed too many times: killing!");
8722            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
8723                    app.info.processName, app.info.uid);
8724            killServicesLocked(app, false);
8725            for (int i=mHistory.size()-1; i>=0; i--) {
8726                HistoryRecord r = (HistoryRecord)mHistory.get(i);
8727                if (r.app == app) {
8728                    Log.w(TAG, "  Force finishing activity "
8729                        + r.intent.getComponent().flattenToShortString());
8730                    finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed");
8731                }
8732            }
8733            if (!app.persistent) {
8734                // We don't want to start this process again until the user
8735                // explicitly does so...  but for persistent process, we really
8736                // need to keep it running.  If a persistent process is actually
8737                // repeatedly crashing, then badness for everyone.
8738                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.info.uid,
8739                        app.info.processName);
8740                mBadProcesses.put(app.info.processName, app.info.uid, now);
8741                app.bad = true;
8742                mProcessCrashTimes.remove(app.info.processName, app.info.uid);
8743                app.removed = true;
8744                removeProcessLocked(app, false);
8745                return false;
8746            }
8747        }
8748
8749        // Bump up the crash count of any services currently running in the proc.
8750        if (app.services.size() != 0) {
8751            // Any services running in the application need to be placed
8752            // back in the pending list.
8753            Iterator it = app.services.iterator();
8754            while (it.hasNext()) {
8755                ServiceRecord sr = (ServiceRecord)it.next();
8756                sr.crashCount++;
8757            }
8758        }
8759
8760        mProcessCrashTimes.put(app.info.processName, app.info.uid, now);
8761        return true;
8762    }
8763
8764    void startAppProblemLocked(ProcessRecord app) {
8765        app.errorReportReceiver = getErrorReportReceiver(app);
8766        skipCurrentReceiverLocked(app);
8767    }
8768
8769    void skipCurrentReceiverLocked(ProcessRecord app) {
8770        boolean reschedule = false;
8771        BroadcastRecord r = app.curReceiver;
8772        if (r != null) {
8773            // The current broadcast is waiting for this app's receiver
8774            // to be finished.  Looks like that's not going to happen, so
8775            // let the broadcast continue.
8776            logBroadcastReceiverDiscard(r);
8777            finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
8778                    r.resultExtras, r.resultAbort, true);
8779            reschedule = true;
8780        }
8781        r = mPendingBroadcast;
8782        if (r != null && r.curApp == app) {
8783            if (DEBUG_BROADCAST) Log.v(TAG,
8784                    "skip & discard pending app " + r);
8785            logBroadcastReceiverDiscard(r);
8786            finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
8787                    r.resultExtras, r.resultAbort, true);
8788            reschedule = true;
8789        }
8790        if (reschedule) {
8791            scheduleBroadcastsLocked();
8792        }
8793    }
8794
8795    /**
8796     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
8797     * The application process will exit immediately after this call returns.
8798     * @param app object of the crashing app, null for the system server
8799     * @param crashInfo describing the exception
8800     */
8801    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
8802        ProcessRecord r = findAppProcess(app);
8803
8804        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
8805                app == null ? "system" : (r == null ? "unknown" : r.processName),
8806                crashInfo.exceptionClassName,
8807                crashInfo.exceptionMessage,
8808                crashInfo.throwFileName,
8809                crashInfo.throwLineNumber);
8810
8811        addExceptionToDropBox("crash", r, null, crashInfo);
8812
8813        crashApplication(r, crashInfo);
8814    }
8815
8816    /**
8817     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
8818     * @param app object of the crashing app, null for the system server
8819     * @param tag reported by the caller
8820     * @param crashInfo describing the context of the error
8821     * @return true if the process should exit immediately (WTF is fatal)
8822     */
8823    public boolean handleApplicationWtf(IBinder app, String tag,
8824            ApplicationErrorReport.CrashInfo crashInfo) {
8825        ProcessRecord r = findAppProcess(app);
8826
8827        EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(),
8828                app == null ? "system" : (r == null ? "unknown" : r.processName),
8829                tag, crashInfo.exceptionMessage);
8830
8831        addExceptionToDropBox("wtf", r, tag, crashInfo);
8832
8833        if (Settings.Gservices.getInt(mContext.getContentResolver(),
8834                Settings.Gservices.WTF_IS_FATAL, 0) != 0) {
8835            crashApplication(r, crashInfo);
8836            return true;
8837        } else {
8838            return false;
8839        }
8840    }
8841
8842    /**
8843     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
8844     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
8845     */
8846    private ProcessRecord findAppProcess(IBinder app) {
8847        if (app == null) {
8848            return null;
8849        }
8850
8851        synchronized (this) {
8852            for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
8853                final int NA = apps.size();
8854                for (int ia=0; ia<NA; ia++) {
8855                    ProcessRecord p = apps.valueAt(ia);
8856                    if (p.thread != null && p.thread.asBinder() == app) {
8857                        return p;
8858                    }
8859                }
8860            }
8861
8862            Log.w(TAG, "Can't find mystery application: " + app);
8863            return null;
8864        }
8865    }
8866
8867    /**
8868     * Write a description of an exception (from a crash or WTF report) to the drop box.
8869     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
8870     * @param r the process which crashed, null for the system server
8871     * @param tag supplied by the application (in the case of WTF), or null
8872     * @param crashInfo describing the exception
8873     */
8874    private void addExceptionToDropBox(String eventType, ProcessRecord r, String tag,
8875            ApplicationErrorReport.CrashInfo crashInfo) {
8876        String dropboxTag, processName;
8877        if (r == null) {
8878            dropboxTag = "system_server_" + eventType;
8879        } else if ((r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
8880            dropboxTag = "system_app_" + eventType;
8881        } else {
8882            dropboxTag = "data_app_" + eventType;
8883        }
8884
8885        DropBoxManager dbox = (DropBoxManager) mContext.getSystemService(Context.DROPBOX_SERVICE);
8886        if (dbox != null && dbox.isTagEnabled(dropboxTag)) {
8887            StringBuilder sb = new StringBuilder(1024);
8888            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
8889            if (r == null) {
8890                sb.append("Process: system_server\n");
8891            } else {
8892                sb.append("Package: ").append(r.info.packageName).append("\n");
8893                if (!r.processName.equals(r.info.packageName)) {
8894                    sb.append("Process: ").append(r.processName).append("\n");
8895                }
8896            }
8897            if (tag != null) {
8898                sb.append("Tag: ").append(tag).append("\n");
8899            }
8900            if (crashInfo != null && crashInfo.stackTrace != null) {
8901                sb.append("\n").append(crashInfo.stackTrace);
8902            }
8903            dbox.addText(dropboxTag, sb.toString());
8904        }
8905    }
8906
8907    /**
8908     * Bring up the "unexpected error" dialog box for a crashing app.
8909     * Deal with edge cases (intercepts from instrumented applications,
8910     * ActivityController, error intent receivers, that sort of thing).
8911     * @param r the application crashing
8912     * @param crashInfo describing the failure
8913     */
8914    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
8915        long timeMillis = System.currentTimeMillis();
8916        String shortMsg = crashInfo.exceptionClassName;
8917        String longMsg = crashInfo.exceptionMessage;
8918        String stackTrace = crashInfo.stackTrace;
8919        if (shortMsg != null && longMsg != null) {
8920            longMsg = shortMsg + ": " + longMsg;
8921        } else if (shortMsg != null) {
8922            longMsg = shortMsg;
8923        }
8924
8925        AppErrorResult result = new AppErrorResult();
8926        synchronized (this) {
8927            if (r != null) {
8928                // The application has crashed. Send the SIGQUIT to the process so
8929                // that it can dump its state.
8930                Process.sendSignal(r.pid, Process.SIGNAL_QUIT);
8931                //Log.i(TAG, "Current system threads:");
8932                //Process.sendSignal(MY_PID, Process.SIGNAL_QUIT);
8933            }
8934
8935            if (mController != null) {
8936                try {
8937                    String name = r != null ? r.processName : null;
8938                    int pid = r != null ? r.pid : Binder.getCallingPid();
8939                    if (!mController.appCrashed(name, pid,
8940                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
8941                        Log.w(TAG, "Force-killing crashed app " + name
8942                                + " at watcher's request");
8943                        Process.killProcess(pid);
8944                        return;
8945                    }
8946                } catch (RemoteException e) {
8947                    mController = null;
8948                }
8949            }
8950
8951            final long origId = Binder.clearCallingIdentity();
8952
8953            // If this process is running instrumentation, finish it.
8954            if (r != null && r.instrumentationClass != null) {
8955                Log.w(TAG, "Error in app " + r.processName
8956                      + " running instrumentation " + r.instrumentationClass + ":");
8957                if (shortMsg != null) Log.w(TAG, "  " + shortMsg);
8958                if (longMsg != null) Log.w(TAG, "  " + longMsg);
8959                Bundle info = new Bundle();
8960                info.putString("shortMsg", shortMsg);
8961                info.putString("longMsg", longMsg);
8962                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
8963                Binder.restoreCallingIdentity(origId);
8964                return;
8965            }
8966
8967            // If we can't identify the process or it's already exceeded its crash quota,
8968            // quit right away without showing a crash dialog.
8969            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
8970                Binder.restoreCallingIdentity(origId);
8971                return;
8972            }
8973
8974            Message msg = Message.obtain();
8975            msg.what = SHOW_ERROR_MSG;
8976            HashMap data = new HashMap();
8977            data.put("result", result);
8978            data.put("app", r);
8979            msg.obj = data;
8980            mHandler.sendMessage(msg);
8981
8982            Binder.restoreCallingIdentity(origId);
8983        }
8984
8985        int res = result.get();
8986
8987        Intent appErrorIntent = null;
8988        synchronized (this) {
8989            if (r != null) {
8990                mProcessCrashTimes.put(r.info.processName, r.info.uid,
8991                        SystemClock.uptimeMillis());
8992            }
8993            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
8994                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
8995            }
8996        }
8997
8998        if (appErrorIntent != null) {
8999            try {
9000                mContext.startActivity(appErrorIntent);
9001            } catch (ActivityNotFoundException e) {
9002                Log.w(TAG, "bug report receiver dissappeared", e);
9003            }
9004        }
9005    }
9006
9007    Intent createAppErrorIntentLocked(ProcessRecord r,
9008            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
9009        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
9010        if (report == null) {
9011            return null;
9012        }
9013        Intent result = new Intent(Intent.ACTION_APP_ERROR);
9014        result.setComponent(r.errorReportReceiver);
9015        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
9016        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
9017        return result;
9018    }
9019
9020    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
9021            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
9022        if (r.errorReportReceiver == null) {
9023            return null;
9024        }
9025
9026        if (!r.crashing && !r.notResponding) {
9027            return null;
9028        }
9029
9030        ApplicationErrorReport report = new ApplicationErrorReport();
9031        report.packageName = r.info.packageName;
9032        report.installerPackageName = r.errorReportReceiver.getPackageName();
9033        report.processName = r.processName;
9034        report.time = timeMillis;
9035
9036        if (r.crashing) {
9037            report.type = ApplicationErrorReport.TYPE_CRASH;
9038            report.crashInfo = crashInfo;
9039        } else if (r.notResponding) {
9040            report.type = ApplicationErrorReport.TYPE_ANR;
9041            report.anrInfo = new ApplicationErrorReport.AnrInfo();
9042
9043            report.anrInfo.activity = r.notRespondingReport.tag;
9044            report.anrInfo.cause = r.notRespondingReport.shortMsg;
9045            report.anrInfo.info = r.notRespondingReport.longMsg;
9046        }
9047
9048        return report;
9049    }
9050
9051    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
9052        // assume our apps are happy - lazy create the list
9053        List<ActivityManager.ProcessErrorStateInfo> errList = null;
9054
9055        synchronized (this) {
9056
9057            // iterate across all processes
9058            for (int i=mLruProcesses.size()-1; i>=0; i--) {
9059                ProcessRecord app = mLruProcesses.get(i);
9060                if ((app.thread != null) && (app.crashing || app.notResponding)) {
9061                    // This one's in trouble, so we'll generate a report for it
9062                    // crashes are higher priority (in case there's a crash *and* an anr)
9063                    ActivityManager.ProcessErrorStateInfo report = null;
9064                    if (app.crashing) {
9065                        report = app.crashingReport;
9066                    } else if (app.notResponding) {
9067                        report = app.notRespondingReport;
9068                    }
9069
9070                    if (report != null) {
9071                        if (errList == null) {
9072                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
9073                        }
9074                        errList.add(report);
9075                    } else {
9076                        Log.w(TAG, "Missing app error report, app = " + app.processName +
9077                                " crashing = " + app.crashing +
9078                                " notResponding = " + app.notResponding);
9079                    }
9080                }
9081            }
9082        }
9083
9084        return errList;
9085    }
9086
9087    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
9088        // Lazy instantiation of list
9089        List<ActivityManager.RunningAppProcessInfo> runList = null;
9090        synchronized (this) {
9091            // Iterate across all processes
9092            for (int i=mLruProcesses.size()-1; i>=0; i--) {
9093                ProcessRecord app = mLruProcesses.get(i);
9094                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
9095                    // Generate process state info for running application
9096                    ActivityManager.RunningAppProcessInfo currApp =
9097                        new ActivityManager.RunningAppProcessInfo(app.processName,
9098                                app.pid, app.getPackageList());
9099                    currApp.uid = app.info.uid;
9100                    int adj = app.curAdj;
9101                    if (adj >= EMPTY_APP_ADJ) {
9102                        currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_EMPTY;
9103                    } else if (adj >= HIDDEN_APP_MIN_ADJ) {
9104                        currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
9105                        currApp.lru = adj - HIDDEN_APP_MIN_ADJ + 1;
9106                    } else if (adj >= HOME_APP_ADJ) {
9107                        currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
9108                        currApp.lru = 0;
9109                    } else if (adj >= SECONDARY_SERVER_ADJ) {
9110                        currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
9111                    } else if (adj >= VISIBLE_APP_ADJ) {
9112                        currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
9113                    } else {
9114                        currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
9115                    }
9116                    currApp.importanceReasonCode = app.adjTypeCode;
9117                    if (app.adjSource instanceof ProcessRecord) {
9118                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
9119                    } else if (app.adjSource instanceof HistoryRecord) {
9120                        HistoryRecord r = (HistoryRecord)app.adjSource;
9121                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
9122                    }
9123                    if (app.adjTarget instanceof ComponentName) {
9124                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
9125                    }
9126                    //Log.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
9127                    //        + " lru=" + currApp.lru);
9128                    if (runList == null) {
9129                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
9130                    }
9131                    runList.add(currApp);
9132                }
9133            }
9134        }
9135        return runList;
9136    }
9137
9138    @Override
9139    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
9140        if (checkCallingPermission(android.Manifest.permission.DUMP)
9141                != PackageManager.PERMISSION_GRANTED) {
9142            pw.println("Permission Denial: can't dump ActivityManager from from pid="
9143                    + Binder.getCallingPid()
9144                    + ", uid=" + Binder.getCallingUid()
9145                    + " without permission "
9146                    + android.Manifest.permission.DUMP);
9147            return;
9148        }
9149
9150        boolean dumpAll = false;
9151
9152        int opti = 0;
9153        while (opti < args.length) {
9154            String opt = args[opti];
9155            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
9156                break;
9157            }
9158            opti++;
9159            if ("-a".equals(opt)) {
9160                dumpAll = true;
9161            } else if ("-h".equals(opt)) {
9162                pw.println("Activity manager dump options:");
9163                pw.println("  [-a] [h- [cmd] ...");
9164                pw.println("  cmd may be one of:");
9165                pw.println("    activities: activity stack state");
9166                pw.println("    broadcasts: broadcast state");
9167                pw.println("    intents: pending intent state");
9168                pw.println("    processes: process state");
9169                pw.println("    providers: content provider state");
9170                pw.println("    services: service state");
9171                pw.println("    service [name]: service client-side state");
9172                return;
9173            } else {
9174                pw.println("Unknown argument: " + opt + "; use -h for help");
9175            }
9176        }
9177
9178        // Is the caller requesting to dump a particular piece of data?
9179        if (opti < args.length) {
9180            String cmd = args[opti];
9181            opti++;
9182            if ("activities".equals(cmd) || "a".equals(cmd)) {
9183                synchronized (this) {
9184                    dumpActivitiesLocked(fd, pw, args, opti, true, true);
9185                }
9186                return;
9187            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
9188                synchronized (this) {
9189                    dumpBroadcastsLocked(fd, pw, args, opti, true);
9190                }
9191                return;
9192            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
9193                synchronized (this) {
9194                    dumpPendingIntentsLocked(fd, pw, args, opti, true);
9195                }
9196                return;
9197            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
9198                synchronized (this) {
9199                    dumpProcessesLocked(fd, pw, args, opti, true);
9200                }
9201                return;
9202            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
9203                synchronized (this) {
9204                    dumpProvidersLocked(fd, pw, args, opti, true);
9205                }
9206                return;
9207            } else if ("service".equals(cmd)) {
9208                dumpService(fd, pw, args, opti, true);
9209                return;
9210            } else if ("services".equals(cmd) || "s".equals(cmd)) {
9211                synchronized (this) {
9212                    dumpServicesLocked(fd, pw, args, opti, true);
9213                }
9214                return;
9215            }
9216        }
9217
9218        // No piece of data specified, dump everything.
9219        synchronized (this) {
9220            boolean needSep;
9221            if (dumpAll) {
9222                pw.println("Providers in Current Activity Manager State:");
9223            }
9224            needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll);
9225            if (needSep) {
9226                pw.println(" ");
9227            }
9228            if (dumpAll) {
9229                pw.println("-------------------------------------------------------------------------------");
9230                pw.println("Broadcasts in Current Activity Manager State:");
9231            }
9232            needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll);
9233            if (needSep) {
9234                pw.println(" ");
9235            }
9236            if (dumpAll) {
9237                pw.println("-------------------------------------------------------------------------------");
9238                pw.println("Services in Current Activity Manager State:");
9239            }
9240            needSep = dumpServicesLocked(fd, pw, args, opti, dumpAll);
9241            if (needSep) {
9242                pw.println(" ");
9243            }
9244            if (dumpAll) {
9245                pw.println("-------------------------------------------------------------------------------");
9246                pw.println("PendingIntents in Current Activity Manager State:");
9247            }
9248            needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll);
9249            if (needSep) {
9250                pw.println(" ");
9251            }
9252            if (dumpAll) {
9253                pw.println("-------------------------------------------------------------------------------");
9254                pw.println("Activities in Current Activity Manager State:");
9255            }
9256            needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, !dumpAll);
9257            if (needSep) {
9258                pw.println(" ");
9259            }
9260            if (dumpAll) {
9261                pw.println("-------------------------------------------------------------------------------");
9262                pw.println("Processes in Current Activity Manager State:");
9263            }
9264            dumpProcessesLocked(fd, pw, args, opti, dumpAll);
9265        }
9266    }
9267
9268    boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9269            int opti, boolean dumpAll, boolean needHeader) {
9270        if (needHeader) {
9271            pw.println("  Activity stack:");
9272        }
9273        dumpHistoryList(pw, mHistory, "  ", "Hist", true);
9274        pw.println(" ");
9275        pw.println("  Running activities (most recent first):");
9276        dumpHistoryList(pw, mLRUActivities, "  ", "Run", false);
9277        if (mWaitingVisibleActivities.size() > 0) {
9278            pw.println(" ");
9279            pw.println("  Activities waiting for another to become visible:");
9280            dumpHistoryList(pw, mWaitingVisibleActivities, "  ", "Wait", false);
9281        }
9282        if (mStoppingActivities.size() > 0) {
9283            pw.println(" ");
9284            pw.println("  Activities waiting to stop:");
9285            dumpHistoryList(pw, mStoppingActivities, "  ", "Stop", false);
9286        }
9287        if (mFinishingActivities.size() > 0) {
9288            pw.println(" ");
9289            pw.println("  Activities waiting to finish:");
9290            dumpHistoryList(pw, mFinishingActivities, "  ", "Fin", false);
9291        }
9292
9293        pw.println(" ");
9294        pw.println("  mPausingActivity: " + mPausingActivity);
9295        pw.println("  mResumedActivity: " + mResumedActivity);
9296        pw.println("  mFocusedActivity: " + mFocusedActivity);
9297        pw.println("  mLastPausedActivity: " + mLastPausedActivity);
9298
9299        if (dumpAll && mRecentTasks.size() > 0) {
9300            pw.println(" ");
9301            pw.println("Recent tasks in Current Activity Manager State:");
9302
9303            final int N = mRecentTasks.size();
9304            for (int i=0; i<N; i++) {
9305                TaskRecord tr = mRecentTasks.get(i);
9306                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
9307                        pw.println(tr);
9308                mRecentTasks.get(i).dump(pw, "    ");
9309            }
9310        }
9311
9312        pw.println(" ");
9313        pw.println("  mCurTask: " + mCurTask);
9314
9315        return true;
9316    }
9317
9318    boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9319            int opti, boolean dumpAll) {
9320        boolean needSep = false;
9321        int numPers = 0;
9322
9323        if (dumpAll) {
9324            for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
9325                final int NA = procs.size();
9326                for (int ia=0; ia<NA; ia++) {
9327                    if (!needSep) {
9328                        pw.println("  All known processes:");
9329                        needSep = true;
9330                    }
9331                    ProcessRecord r = procs.valueAt(ia);
9332                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
9333                        pw.print(" UID "); pw.print(procs.keyAt(ia));
9334                        pw.print(" "); pw.println(r);
9335                    r.dump(pw, "    ");
9336                    if (r.persistent) {
9337                        numPers++;
9338                    }
9339                }
9340            }
9341        }
9342
9343        if (mLruProcesses.size() > 0) {
9344            if (needSep) pw.println(" ");
9345            needSep = true;
9346            pw.println("  Running processes (most recent first):");
9347            dumpProcessList(pw, this, mLruProcesses, "    ",
9348                    "App ", "PERS", true);
9349            needSep = true;
9350        }
9351
9352        synchronized (mPidsSelfLocked) {
9353            if (mPidsSelfLocked.size() > 0) {
9354                if (needSep) pw.println(" ");
9355                needSep = true;
9356                pw.println("  PID mappings:");
9357                for (int i=0; i<mPidsSelfLocked.size(); i++) {
9358                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
9359                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
9360                }
9361            }
9362        }
9363
9364        if (mForegroundProcesses.size() > 0) {
9365            if (needSep) pw.println(" ");
9366            needSep = true;
9367            pw.println("  Foreground Processes:");
9368            for (int i=0; i<mForegroundProcesses.size(); i++) {
9369                pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
9370                        pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
9371            }
9372        }
9373
9374        if (mPersistentStartingProcesses.size() > 0) {
9375            if (needSep) pw.println(" ");
9376            needSep = true;
9377            pw.println("  Persisent processes that are starting:");
9378            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
9379                    "Starting Norm", "Restarting PERS", false);
9380        }
9381
9382        if (mStartingProcesses.size() > 0) {
9383            if (needSep) pw.println(" ");
9384            needSep = true;
9385            pw.println("  Processes that are starting:");
9386            dumpProcessList(pw, this, mStartingProcesses, "    ",
9387                    "Starting Norm", "Starting PERS", false);
9388        }
9389
9390        if (mRemovedProcesses.size() > 0) {
9391            if (needSep) pw.println(" ");
9392            needSep = true;
9393            pw.println("  Processes that are being removed:");
9394            dumpProcessList(pw, this, mRemovedProcesses, "    ",
9395                    "Removed Norm", "Removed PERS", false);
9396        }
9397
9398        if (mProcessesOnHold.size() > 0) {
9399            if (needSep) pw.println(" ");
9400            needSep = true;
9401            pw.println("  Processes that are on old until the system is ready:");
9402            dumpProcessList(pw, this, mProcessesOnHold, "    ",
9403                    "OnHold Norm", "OnHold PERS", false);
9404        }
9405
9406        if (mProcessesToGc.size() > 0) {
9407            if (needSep) pw.println(" ");
9408            needSep = true;
9409            pw.println("  Processes that are waiting to GC:");
9410            long now = SystemClock.uptimeMillis();
9411            for (int i=0; i<mProcessesToGc.size(); i++) {
9412                ProcessRecord proc = mProcessesToGc.get(i);
9413                pw.print("    Process "); pw.println(proc);
9414                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
9415                        pw.print(", last gced=");
9416                        pw.print(now-proc.lastRequestedGc);
9417                        pw.print(" ms ago, last lowMem=");
9418                        pw.print(now-proc.lastLowMemory);
9419                        pw.println(" ms ago");
9420
9421            }
9422        }
9423
9424        if (mProcessCrashTimes.getMap().size() > 0) {
9425            if (needSep) pw.println(" ");
9426            needSep = true;
9427            pw.println("  Time since processes crashed:");
9428            long now = SystemClock.uptimeMillis();
9429            for (Map.Entry<String, SparseArray<Long>> procs
9430                    : mProcessCrashTimes.getMap().entrySet()) {
9431                SparseArray<Long> uids = procs.getValue();
9432                final int N = uids.size();
9433                for (int i=0; i<N; i++) {
9434                    pw.print("    Process "); pw.print(procs.getKey());
9435                            pw.print(" uid "); pw.print(uids.keyAt(i));
9436                            pw.print(": last crashed ");
9437                            pw.print((now-uids.valueAt(i)));
9438                            pw.println(" ms ago");
9439                }
9440            }
9441        }
9442
9443        if (mBadProcesses.getMap().size() > 0) {
9444            if (needSep) pw.println(" ");
9445            needSep = true;
9446            pw.println("  Bad processes:");
9447            for (Map.Entry<String, SparseArray<Long>> procs
9448                    : mBadProcesses.getMap().entrySet()) {
9449                SparseArray<Long> uids = procs.getValue();
9450                final int N = uids.size();
9451                for (int i=0; i<N; i++) {
9452                    pw.print("    Bad process "); pw.print(procs.getKey());
9453                            pw.print(" uid "); pw.print(uids.keyAt(i));
9454                            pw.print(": crashed at time ");
9455                            pw.println(uids.valueAt(i));
9456                }
9457            }
9458        }
9459
9460        pw.println(" ");
9461        pw.println("  mHomeProcess: " + mHomeProcess);
9462        pw.println("  mConfiguration: " + mConfiguration);
9463        pw.println("  mSleeping=" + mSleeping + " mShuttingDown=" + mShuttingDown);
9464        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
9465                || mOrigWaitForDebugger) {
9466            pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
9467                    + " mDebugTransient=" + mDebugTransient
9468                    + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
9469        }
9470        if (mAlwaysFinishActivities || mController != null) {
9471            pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
9472                    + " mController=" + mController);
9473        }
9474        if (dumpAll) {
9475            pw.println("  Total persistent processes: " + numPers);
9476            pw.println("  mStartRunning=" + mStartRunning
9477                    + " mSystemReady=" + mSystemReady
9478                    + " mBooting=" + mBooting
9479                    + " mBooted=" + mBooted
9480                    + " mFactoryTest=" + mFactoryTest);
9481            pw.println("  mGoingToSleep=" + mGoingToSleep);
9482            pw.println("  mLaunchingActivity=" + mLaunchingActivity);
9483        }
9484
9485        return true;
9486    }
9487
9488    /**
9489     * There are three ways to call this:
9490     *  - no service specified: dump all the services
9491     *  - a flattened component name that matched an existing service was specified as the
9492     *    first arg: dump that one service
9493     *  - the first arg isn't the flattened component name of an existing service:
9494     *    dump all services whose component contains the first arg as a substring
9495     */
9496    protected void dumpService(FileDescriptor fd, PrintWriter pw, String[] args,
9497            int opti, boolean dumpAll) {
9498        String[] newArgs;
9499        String componentNameString;
9500        ServiceRecord r;
9501        if (opti <= args.length) {
9502            componentNameString = null;
9503            newArgs = EMPTY_STRING_ARRAY;
9504            r = null;
9505        } else {
9506            componentNameString = args[opti];
9507            opti++;
9508            ComponentName componentName = ComponentName.unflattenFromString(componentNameString);
9509            r = componentName != null ? mServices.get(componentName) : null;
9510            newArgs = new String[args.length - opti];
9511            if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
9512        }
9513
9514        if (r != null) {
9515            dumpService(fd, pw, r, newArgs);
9516        } else {
9517            for (ServiceRecord r1 : mServices.values()) {
9518                if (componentNameString == null
9519                        || r1.name.flattenToString().contains(componentNameString)) {
9520                    dumpService(fd, pw, r1, newArgs);
9521                }
9522            }
9523        }
9524    }
9525
9526    /**
9527     * Invokes IApplicationThread.dumpService() on the thread of the specified service if
9528     * there is a thread associated with the service.
9529     */
9530    private void dumpService(FileDescriptor fd, PrintWriter pw, ServiceRecord r, String[] args) {
9531        pw.println("  Service " + r.name.flattenToString());
9532        if (r.app != null && r.app.thread != null) {
9533            try {
9534                // flush anything that is already in the PrintWriter since the thread is going
9535                // to write to the file descriptor directly
9536                pw.flush();
9537                r.app.thread.dumpService(fd, r, args);
9538                pw.print("\n");
9539            } catch (RemoteException e) {
9540                pw.println("got a RemoteException while dumping the service");
9541            }
9542        }
9543    }
9544
9545    boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9546            int opti, boolean dumpAll) {
9547        boolean needSep = false;
9548
9549        if (dumpAll) {
9550            if (mRegisteredReceivers.size() > 0) {
9551                pw.println(" ");
9552                pw.println("  Registered Receivers:");
9553                Iterator it = mRegisteredReceivers.values().iterator();
9554                while (it.hasNext()) {
9555                    ReceiverList r = (ReceiverList)it.next();
9556                    pw.print("  * "); pw.println(r);
9557                    r.dump(pw, "    ");
9558                }
9559            }
9560
9561            pw.println(" ");
9562            pw.println("Receiver Resolver Table:");
9563            mReceiverResolver.dump(pw, "  ");
9564            needSep = true;
9565        }
9566
9567        if (mParallelBroadcasts.size() > 0 || mOrderedBroadcasts.size() > 0
9568                || mPendingBroadcast != null) {
9569            if (mParallelBroadcasts.size() > 0) {
9570                pw.println(" ");
9571                pw.println("  Active broadcasts:");
9572            }
9573            for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
9574                pw.println("  Broadcast #" + i + ":");
9575                mParallelBroadcasts.get(i).dump(pw, "    ");
9576            }
9577            if (mOrderedBroadcasts.size() > 0) {
9578                pw.println(" ");
9579                pw.println("  Active serialized broadcasts:");
9580            }
9581            for (int i=mOrderedBroadcasts.size()-1; i>=0; i--) {
9582                pw.println("  Serialized Broadcast #" + i + ":");
9583                mOrderedBroadcasts.get(i).dump(pw, "    ");
9584            }
9585            pw.println(" ");
9586            pw.println("  Pending broadcast:");
9587            if (mPendingBroadcast != null) {
9588                mPendingBroadcast.dump(pw, "    ");
9589            } else {
9590                pw.println("    (null)");
9591            }
9592            needSep = true;
9593        }
9594
9595        if (dumpAll) {
9596            pw.println(" ");
9597            pw.println("  Historical broadcasts:");
9598            for (int i=0; i<MAX_BROADCAST_HISTORY; i++) {
9599                BroadcastRecord r = mBroadcastHistory[i];
9600                if (r == null) {
9601                    break;
9602                }
9603                pw.println("  Historical Broadcast #" + i + ":");
9604                r.dump(pw, "    ");
9605            }
9606            needSep = true;
9607        }
9608
9609        if (mStickyBroadcasts != null) {
9610            pw.println(" ");
9611            pw.println("  Sticky broadcasts:");
9612            StringBuilder sb = new StringBuilder(128);
9613            for (Map.Entry<String, ArrayList<Intent>> ent
9614                    : mStickyBroadcasts.entrySet()) {
9615                pw.print("  * Sticky action "); pw.print(ent.getKey());
9616                        pw.println(":");
9617                ArrayList<Intent> intents = ent.getValue();
9618                final int N = intents.size();
9619                for (int i=0; i<N; i++) {
9620                    sb.setLength(0);
9621                    sb.append("    Intent: ");
9622                    intents.get(i).toShortString(sb, true, false);
9623                    pw.println(sb.toString());
9624                    Bundle bundle = intents.get(i).getExtras();
9625                    if (bundle != null) {
9626                        pw.print("      ");
9627                        pw.println(bundle.toString());
9628                    }
9629                }
9630            }
9631            needSep = true;
9632        }
9633
9634        if (dumpAll) {
9635            pw.println(" ");
9636            pw.println("  mBroadcastsScheduled=" + mBroadcastsScheduled);
9637            pw.println("  mHandler:");
9638            mHandler.dump(new PrintWriterPrinter(pw), "    ");
9639            needSep = true;
9640        }
9641
9642        return needSep;
9643    }
9644
9645    boolean dumpServicesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9646            int opti, boolean dumpAll) {
9647        boolean needSep = false;
9648
9649        if (dumpAll) {
9650            if (mServices.size() > 0) {
9651                pw.println("  Active services:");
9652                Iterator<ServiceRecord> it = mServices.values().iterator();
9653                while (it.hasNext()) {
9654                    ServiceRecord r = it.next();
9655                    pw.print("  * "); pw.println(r);
9656                    r.dump(pw, "    ");
9657                }
9658                needSep = true;
9659            }
9660        }
9661
9662        if (mPendingServices.size() > 0) {
9663            if (needSep) pw.println(" ");
9664            pw.println("  Pending services:");
9665            for (int i=0; i<mPendingServices.size(); i++) {
9666                ServiceRecord r = mPendingServices.get(i);
9667                pw.print("  * Pending "); pw.println(r);
9668                r.dump(pw, "    ");
9669            }
9670            needSep = true;
9671        }
9672
9673        if (mRestartingServices.size() > 0) {
9674            if (needSep) pw.println(" ");
9675            pw.println("  Restarting services:");
9676            for (int i=0; i<mRestartingServices.size(); i++) {
9677                ServiceRecord r = mRestartingServices.get(i);
9678                pw.print("  * Restarting "); pw.println(r);
9679                r.dump(pw, "    ");
9680            }
9681            needSep = true;
9682        }
9683
9684        if (mStoppingServices.size() > 0) {
9685            if (needSep) pw.println(" ");
9686            pw.println("  Stopping services:");
9687            for (int i=0; i<mStoppingServices.size(); i++) {
9688                ServiceRecord r = mStoppingServices.get(i);
9689                pw.print("  * Stopping "); pw.println(r);
9690                r.dump(pw, "    ");
9691            }
9692            needSep = true;
9693        }
9694
9695        if (dumpAll) {
9696            if (mServiceConnections.size() > 0) {
9697                if (needSep) pw.println(" ");
9698                pw.println("  Connection bindings to services:");
9699                Iterator<ConnectionRecord> it
9700                        = mServiceConnections.values().iterator();
9701                while (it.hasNext()) {
9702                    ConnectionRecord r = it.next();
9703                    pw.print("  * "); pw.println(r);
9704                    r.dump(pw, "    ");
9705                }
9706                needSep = true;
9707            }
9708        }
9709
9710        return needSep;
9711    }
9712
9713    boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9714            int opti, boolean dumpAll) {
9715        boolean needSep = false;
9716
9717        if (dumpAll) {
9718            if (mProvidersByClass.size() > 0) {
9719                if (needSep) pw.println(" ");
9720                pw.println("  Published content providers (by class):");
9721                Iterator it = mProvidersByClass.entrySet().iterator();
9722                while (it.hasNext()) {
9723                    Map.Entry e = (Map.Entry)it.next();
9724                    ContentProviderRecord r = (ContentProviderRecord)e.getValue();
9725                    pw.print("  * "); pw.println(r);
9726                    r.dump(pw, "    ");
9727                }
9728                needSep = true;
9729            }
9730
9731            if (mProvidersByName.size() > 0) {
9732                pw.println(" ");
9733                pw.println("  Authority to provider mappings:");
9734                Iterator it = mProvidersByName.entrySet().iterator();
9735                while (it.hasNext()) {
9736                    Map.Entry e = (Map.Entry)it.next();
9737                    ContentProviderRecord r = (ContentProviderRecord)e.getValue();
9738                    pw.print("  "); pw.print(e.getKey()); pw.print(": ");
9739                            pw.println(r);
9740                }
9741                needSep = true;
9742            }
9743        }
9744
9745        if (mLaunchingProviders.size() > 0) {
9746            if (needSep) pw.println(" ");
9747            pw.println("  Launching content providers:");
9748            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
9749                pw.print("  Launching #"); pw.print(i); pw.print(": ");
9750                        pw.println(mLaunchingProviders.get(i));
9751            }
9752            needSep = true;
9753        }
9754
9755        if (mGrantedUriPermissions.size() > 0) {
9756            pw.println();
9757            pw.println("Granted Uri Permissions:");
9758            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
9759                int uid = mGrantedUriPermissions.keyAt(i);
9760                HashMap<Uri, UriPermission> perms
9761                        = mGrantedUriPermissions.valueAt(i);
9762                pw.print("  * UID "); pw.print(uid);
9763                        pw.println(" holds:");
9764                for (UriPermission perm : perms.values()) {
9765                    pw.print("    "); pw.println(perm);
9766                    perm.dump(pw, "      ");
9767                }
9768            }
9769            needSep = true;
9770        }
9771
9772        return needSep;
9773    }
9774
9775    boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9776            int opti, boolean dumpAll) {
9777        boolean needSep = false;
9778
9779        if (dumpAll) {
9780            if (this.mIntentSenderRecords.size() > 0) {
9781                Iterator<WeakReference<PendingIntentRecord>> it
9782                        = mIntentSenderRecords.values().iterator();
9783                while (it.hasNext()) {
9784                    WeakReference<PendingIntentRecord> ref = it.next();
9785                    PendingIntentRecord rec = ref != null ? ref.get(): null;
9786                    needSep = true;
9787                    if (rec != null) {
9788                        pw.print("  * "); pw.println(rec);
9789                        rec.dump(pw, "    ");
9790                    } else {
9791                        pw.print("  * "); pw.print(ref);
9792                    }
9793                }
9794            }
9795        }
9796
9797        return needSep;
9798    }
9799
9800    private static final void dumpHistoryList(PrintWriter pw, List list,
9801            String prefix, String label, boolean complete) {
9802        TaskRecord lastTask = null;
9803        for (int i=list.size()-1; i>=0; i--) {
9804            HistoryRecord r = (HistoryRecord)list.get(i);
9805            final boolean full = complete || !r.inHistory;
9806            if (lastTask != r.task) {
9807                lastTask = r.task;
9808                pw.print(prefix);
9809                pw.print(full ? "* " : "  ");
9810                pw.println(lastTask);
9811                if (full) {
9812                    lastTask.dump(pw, prefix + "  ");
9813                }
9814            }
9815            pw.print(prefix); pw.print(full ? "  * " : "    "); pw.print(label);
9816            pw.print(" #"); pw.print(i); pw.print(": ");
9817            pw.println(r);
9818            if (full) {
9819                r.dump(pw, prefix + "      ");
9820            }
9821        }
9822    }
9823
9824    private static String buildOomTag(String prefix, String space, int val, int base) {
9825        if (val == base) {
9826            if (space == null) return prefix;
9827            return prefix + "  ";
9828        }
9829        return prefix + "+" + Integer.toString(val-base);
9830    }
9831
9832    private static final int dumpProcessList(PrintWriter pw,
9833            ActivityManagerService service, List list,
9834            String prefix, String normalLabel, String persistentLabel,
9835            boolean inclOomAdj) {
9836        int numPers = 0;
9837        for (int i=list.size()-1; i>=0; i--) {
9838            ProcessRecord r = (ProcessRecord)list.get(i);
9839            if (false) {
9840                pw.println(prefix + (r.persistent ? persistentLabel : normalLabel)
9841                      + " #" + i + ":");
9842                r.dump(pw, prefix + "  ");
9843            } else if (inclOomAdj) {
9844                String oomAdj;
9845                if (r.setAdj >= EMPTY_APP_ADJ) {
9846                    oomAdj = buildOomTag("empty", null, r.setAdj, EMPTY_APP_ADJ);
9847                } else if (r.setAdj >= HIDDEN_APP_MIN_ADJ) {
9848                    oomAdj = buildOomTag("bak", "  ", r.setAdj, HIDDEN_APP_MIN_ADJ);
9849                } else if (r.setAdj >= HOME_APP_ADJ) {
9850                    oomAdj = buildOomTag("home ", null, r.setAdj, HOME_APP_ADJ);
9851                } else if (r.setAdj >= SECONDARY_SERVER_ADJ) {
9852                    oomAdj = buildOomTag("svc", "  ", r.setAdj, SECONDARY_SERVER_ADJ);
9853                } else if (r.setAdj >= BACKUP_APP_ADJ) {
9854                    oomAdj = buildOomTag("bckup", null, r.setAdj, BACKUP_APP_ADJ);
9855                } else if (r.setAdj >= VISIBLE_APP_ADJ) {
9856                    oomAdj = buildOomTag("vis  ", null, r.setAdj, VISIBLE_APP_ADJ);
9857                } else if (r.setAdj >= FOREGROUND_APP_ADJ) {
9858                    oomAdj = buildOomTag("fore ", null, r.setAdj, FOREGROUND_APP_ADJ);
9859                } else if (r.setAdj >= CORE_SERVER_ADJ) {
9860                    oomAdj = buildOomTag("core ", null, r.setAdj, CORE_SERVER_ADJ);
9861                } else if (r.setAdj >= SYSTEM_ADJ) {
9862                    oomAdj = buildOomTag("sys  ", null, r.setAdj, SYSTEM_ADJ);
9863                } else {
9864                    oomAdj = Integer.toString(r.setAdj);
9865                }
9866                String schedGroup;
9867                switch (r.setSchedGroup) {
9868                    case Process.THREAD_GROUP_BG_NONINTERACTIVE:
9869                        schedGroup = "B";
9870                        break;
9871                    case Process.THREAD_GROUP_DEFAULT:
9872                        schedGroup = "F";
9873                        break;
9874                    default:
9875                        schedGroup = Integer.toString(r.setSchedGroup);
9876                        break;
9877                }
9878                pw.println(String.format("%s%s #%2d: adj=%s/%s %s (%s)",
9879                        prefix, (r.persistent ? persistentLabel : normalLabel),
9880                        i, oomAdj, schedGroup, r.toShortString(), r.adjType));
9881                if (r.adjSource != null || r.adjTarget != null) {
9882                    pw.println(prefix + "          " + r.adjTarget
9883                            + "<=" + r.adjSource);
9884                }
9885            } else {
9886                pw.println(String.format("%s%s #%2d: %s",
9887                        prefix, (r.persistent ? persistentLabel : normalLabel),
9888                        i, r.toString()));
9889            }
9890            if (r.persistent) {
9891                numPers++;
9892            }
9893        }
9894        return numPers;
9895    }
9896
9897    private static final void dumpApplicationMemoryUsage(FileDescriptor fd,
9898            PrintWriter pw, List list, String prefix, String[] args) {
9899        final boolean isCheckinRequest = scanArgs(args, "--checkin");
9900        long uptime = SystemClock.uptimeMillis();
9901        long realtime = SystemClock.elapsedRealtime();
9902
9903        if (isCheckinRequest) {
9904            // short checkin version
9905            pw.println(uptime + "," + realtime);
9906            pw.flush();
9907        } else {
9908            pw.println("Applications Memory Usage (kB):");
9909            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
9910        }
9911        for (int i = list.size() - 1 ; i >= 0 ; i--) {
9912            ProcessRecord r = (ProcessRecord)list.get(i);
9913            if (r.thread != null) {
9914                if (!isCheckinRequest) {
9915                    pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
9916                    pw.flush();
9917                }
9918                try {
9919                    r.thread.asBinder().dump(fd, args);
9920                } catch (RemoteException e) {
9921                    if (!isCheckinRequest) {
9922                        pw.println("Got RemoteException!");
9923                        pw.flush();
9924                    }
9925                }
9926            }
9927        }
9928    }
9929
9930    /**
9931     * Searches array of arguments for the specified string
9932     * @param args array of argument strings
9933     * @param value value to search for
9934     * @return true if the value is contained in the array
9935     */
9936    private static boolean scanArgs(String[] args, String value) {
9937        if (args != null) {
9938            for (String arg : args) {
9939                if (value.equals(arg)) {
9940                    return true;
9941                }
9942            }
9943        }
9944        return false;
9945    }
9946
9947    private final int indexOfTokenLocked(IBinder token) {
9948        int count = mHistory.size();
9949
9950        // convert the token to an entry in the history.
9951        HistoryRecord r = null;
9952        int index = -1;
9953        for (int i=count-1; i>=0; i--) {
9954            Object o = mHistory.get(i);
9955            if (o == token) {
9956                r = (HistoryRecord)o;
9957                index = i;
9958                break;
9959            }
9960        }
9961
9962        return index;
9963    }
9964
9965    private final void killServicesLocked(ProcessRecord app,
9966            boolean allowRestart) {
9967        // Report disconnected services.
9968        if (false) {
9969            // XXX we are letting the client link to the service for
9970            // death notifications.
9971            if (app.services.size() > 0) {
9972                Iterator it = app.services.iterator();
9973                while (it.hasNext()) {
9974                    ServiceRecord r = (ServiceRecord)it.next();
9975                    if (r.connections.size() > 0) {
9976                        Iterator<ConnectionRecord> jt
9977                                = r.connections.values().iterator();
9978                        while (jt.hasNext()) {
9979                            ConnectionRecord c = jt.next();
9980                            if (c.binding.client != app) {
9981                                try {
9982                                    //c.conn.connected(r.className, null);
9983                                } catch (Exception e) {
9984                                    // todo: this should be asynchronous!
9985                                    Log.w(TAG, "Exception thrown disconnected servce "
9986                                          + r.shortName
9987                                          + " from app " + app.processName, e);
9988                                }
9989                            }
9990                        }
9991                    }
9992                }
9993            }
9994        }
9995
9996        // Clean up any connections this application has to other services.
9997        if (app.connections.size() > 0) {
9998            Iterator<ConnectionRecord> it = app.connections.iterator();
9999            while (it.hasNext()) {
10000                ConnectionRecord r = it.next();
10001                removeConnectionLocked(r, app, null);
10002            }
10003        }
10004        app.connections.clear();
10005
10006        if (app.services.size() != 0) {
10007            // Any services running in the application need to be placed
10008            // back in the pending list.
10009            Iterator it = app.services.iterator();
10010            while (it.hasNext()) {
10011                ServiceRecord sr = (ServiceRecord)it.next();
10012                synchronized (sr.stats.getBatteryStats()) {
10013                    sr.stats.stopLaunchedLocked();
10014                }
10015                sr.app = null;
10016                sr.executeNesting = 0;
10017                mStoppingServices.remove(sr);
10018
10019                boolean hasClients = sr.bindings.size() > 0;
10020                if (hasClients) {
10021                    Iterator<IntentBindRecord> bindings
10022                            = sr.bindings.values().iterator();
10023                    while (bindings.hasNext()) {
10024                        IntentBindRecord b = bindings.next();
10025                        if (DEBUG_SERVICE) Log.v(TAG, "Killing binding " + b
10026                                + ": shouldUnbind=" + b.hasBound);
10027                        b.binder = null;
10028                        b.requested = b.received = b.hasBound = false;
10029                    }
10030                }
10031
10032                if (sr.crashCount >= 2) {
10033                    Log.w(TAG, "Service crashed " + sr.crashCount
10034                            + " times, stopping: " + sr);
10035                    EventLog.writeEvent(EventLogTags.AM_SERVICE_CRASHED_TOO_MUCH,
10036                            sr.crashCount, sr.shortName, app.pid);
10037                    bringDownServiceLocked(sr, true);
10038                } else if (!allowRestart) {
10039                    bringDownServiceLocked(sr, true);
10040                } else {
10041                    boolean canceled = scheduleServiceRestartLocked(sr, true);
10042
10043                    // Should the service remain running?  Note that in the
10044                    // extreme case of so many attempts to deliver a command
10045                    // that it failed, that we also will stop it here.
10046                    if (sr.startRequested && (sr.stopIfKilled || canceled)) {
10047                        if (sr.pendingStarts.size() == 0) {
10048                            sr.startRequested = false;
10049                            if (!hasClients) {
10050                                // Whoops, no reason to restart!
10051                                bringDownServiceLocked(sr, true);
10052                            }
10053                        }
10054                    }
10055                }
10056            }
10057
10058            if (!allowRestart) {
10059                app.services.clear();
10060            }
10061        }
10062
10063        // Make sure we have no more records on the stopping list.
10064        int i = mStoppingServices.size();
10065        while (i > 0) {
10066            i--;
10067            ServiceRecord sr = mStoppingServices.get(i);
10068            if (sr.app == app) {
10069                mStoppingServices.remove(i);
10070            }
10071        }
10072
10073        app.executingServices.clear();
10074    }
10075
10076    private final void removeDyingProviderLocked(ProcessRecord proc,
10077            ContentProviderRecord cpr) {
10078        synchronized (cpr) {
10079            cpr.launchingApp = null;
10080            cpr.notifyAll();
10081        }
10082
10083        mProvidersByClass.remove(cpr.info.name);
10084        String names[] = cpr.info.authority.split(";");
10085        for (int j = 0; j < names.length; j++) {
10086            mProvidersByName.remove(names[j]);
10087        }
10088
10089        Iterator<ProcessRecord> cit = cpr.clients.iterator();
10090        while (cit.hasNext()) {
10091            ProcessRecord capp = cit.next();
10092            if (!capp.persistent && capp.thread != null
10093                    && capp.pid != 0
10094                    && capp.pid != MY_PID) {
10095                Log.i(TAG, "Killing app " + capp.processName
10096                        + " (pid " + capp.pid
10097                        + ") because provider " + cpr.info.name
10098                        + " is in dying process " + proc.processName);
10099                Process.killProcess(capp.pid);
10100            }
10101        }
10102
10103        mLaunchingProviders.remove(cpr);
10104    }
10105
10106    /**
10107     * Main code for cleaning up a process when it has gone away.  This is
10108     * called both as a result of the process dying, or directly when stopping
10109     * a process when running in single process mode.
10110     */
10111    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
10112            boolean restarting, int index) {
10113        if (index >= 0) {
10114            mLruProcesses.remove(index);
10115        }
10116
10117        mProcessesToGc.remove(app);
10118
10119        // Dismiss any open dialogs.
10120        if (app.crashDialog != null) {
10121            app.crashDialog.dismiss();
10122            app.crashDialog = null;
10123        }
10124        if (app.anrDialog != null) {
10125            app.anrDialog.dismiss();
10126            app.anrDialog = null;
10127        }
10128        if (app.waitDialog != null) {
10129            app.waitDialog.dismiss();
10130            app.waitDialog = null;
10131        }
10132
10133        app.crashing = false;
10134        app.notResponding = false;
10135
10136        app.resetPackageList();
10137        app.thread = null;
10138        app.forcingToForeground = null;
10139        app.foregroundServices = false;
10140
10141        killServicesLocked(app, true);
10142
10143        boolean restart = false;
10144
10145        int NL = mLaunchingProviders.size();
10146
10147        // Remove published content providers.
10148        if (!app.pubProviders.isEmpty()) {
10149            Iterator it = app.pubProviders.values().iterator();
10150            while (it.hasNext()) {
10151                ContentProviderRecord cpr = (ContentProviderRecord)it.next();
10152                cpr.provider = null;
10153                cpr.app = null;
10154
10155                // See if someone is waiting for this provider...  in which
10156                // case we don't remove it, but just let it restart.
10157                int i = 0;
10158                if (!app.bad) {
10159                    for (; i<NL; i++) {
10160                        if (mLaunchingProviders.get(i) == cpr) {
10161                            restart = true;
10162                            break;
10163                        }
10164                    }
10165                } else {
10166                    i = NL;
10167                }
10168
10169                if (i >= NL) {
10170                    removeDyingProviderLocked(app, cpr);
10171                    NL = mLaunchingProviders.size();
10172                }
10173            }
10174            app.pubProviders.clear();
10175        }
10176
10177        // Take care of any launching providers waiting for this process.
10178        if (checkAppInLaunchingProvidersLocked(app, false)) {
10179            restart = true;
10180        }
10181
10182        // Unregister from connected content providers.
10183        if (!app.conProviders.isEmpty()) {
10184            Iterator it = app.conProviders.keySet().iterator();
10185            while (it.hasNext()) {
10186                ContentProviderRecord cpr = (ContentProviderRecord)it.next();
10187                cpr.clients.remove(app);
10188            }
10189            app.conProviders.clear();
10190        }
10191
10192        // At this point there may be remaining entries in mLaunchingProviders
10193        // where we were the only one waiting, so they are no longer of use.
10194        // Look for these and clean up if found.
10195        // XXX Commented out for now.  Trying to figure out a way to reproduce
10196        // the actual situation to identify what is actually going on.
10197        if (false) {
10198            for (int i=0; i<NL; i++) {
10199                ContentProviderRecord cpr = (ContentProviderRecord)
10200                        mLaunchingProviders.get(i);
10201                if (cpr.clients.size() <= 0 && cpr.externals <= 0) {
10202                    synchronized (cpr) {
10203                        cpr.launchingApp = null;
10204                        cpr.notifyAll();
10205                    }
10206                }
10207            }
10208        }
10209
10210        skipCurrentReceiverLocked(app);
10211
10212        // Unregister any receivers.
10213        if (app.receivers.size() > 0) {
10214            Iterator<ReceiverList> it = app.receivers.iterator();
10215            while (it.hasNext()) {
10216                removeReceiverLocked(it.next());
10217            }
10218            app.receivers.clear();
10219        }
10220
10221        // If the app is undergoing backup, tell the backup manager about it
10222        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
10223            if (DEBUG_BACKUP) Log.d(TAG, "App " + mBackupTarget.appInfo + " died during backup");
10224            try {
10225                IBackupManager bm = IBackupManager.Stub.asInterface(
10226                        ServiceManager.getService(Context.BACKUP_SERVICE));
10227                bm.agentDisconnected(app.info.packageName);
10228            } catch (RemoteException e) {
10229                // can't happen; backup manager is local
10230            }
10231        }
10232
10233        // If the caller is restarting this app, then leave it in its
10234        // current lists and let the caller take care of it.
10235        if (restarting) {
10236            return;
10237        }
10238
10239        if (!app.persistent) {
10240            if (DEBUG_PROCESSES) Log.v(TAG,
10241                    "Removing non-persistent process during cleanup: " + app);
10242            mProcessNames.remove(app.processName, app.info.uid);
10243        } else if (!app.removed) {
10244            // This app is persistent, so we need to keep its record around.
10245            // If it is not already on the pending app list, add it there
10246            // and start a new process for it.
10247            app.thread = null;
10248            app.forcingToForeground = null;
10249            app.foregroundServices = false;
10250            if (mPersistentStartingProcesses.indexOf(app) < 0) {
10251                mPersistentStartingProcesses.add(app);
10252                restart = true;
10253            }
10254        }
10255        mProcessesOnHold.remove(app);
10256
10257        if (app == mHomeProcess) {
10258            mHomeProcess = null;
10259        }
10260
10261        if (restart) {
10262            // We have components that still need to be running in the
10263            // process, so re-launch it.
10264            mProcessNames.put(app.processName, app.info.uid, app);
10265            startProcessLocked(app, "restart", app.processName);
10266        } else if (app.pid > 0 && app.pid != MY_PID) {
10267            // Goodbye!
10268            synchronized (mPidsSelfLocked) {
10269                mPidsSelfLocked.remove(app.pid);
10270                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
10271            }
10272            app.setPid(0);
10273        }
10274    }
10275
10276    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
10277        // Look through the content providers we are waiting to have launched,
10278        // and if any run in this process then either schedule a restart of
10279        // the process or kill the client waiting for it if this process has
10280        // gone bad.
10281        int NL = mLaunchingProviders.size();
10282        boolean restart = false;
10283        for (int i=0; i<NL; i++) {
10284            ContentProviderRecord cpr = (ContentProviderRecord)
10285                    mLaunchingProviders.get(i);
10286            if (cpr.launchingApp == app) {
10287                if (!alwaysBad && !app.bad) {
10288                    restart = true;
10289                } else {
10290                    removeDyingProviderLocked(app, cpr);
10291                    NL = mLaunchingProviders.size();
10292                }
10293            }
10294        }
10295        return restart;
10296    }
10297
10298    // =========================================================
10299    // SERVICES
10300    // =========================================================
10301
10302    ActivityManager.RunningServiceInfo makeRunningServiceInfoLocked(ServiceRecord r) {
10303        ActivityManager.RunningServiceInfo info =
10304            new ActivityManager.RunningServiceInfo();
10305        info.service = r.name;
10306        if (r.app != null) {
10307            info.pid = r.app.pid;
10308        }
10309        info.uid = r.appInfo.uid;
10310        info.process = r.processName;
10311        info.foreground = r.isForeground;
10312        info.activeSince = r.createTime;
10313        info.started = r.startRequested;
10314        info.clientCount = r.connections.size();
10315        info.crashCount = r.crashCount;
10316        info.lastActivityTime = r.lastActivity;
10317        if (r.isForeground) {
10318            info.flags |= ActivityManager.RunningServiceInfo.FLAG_FOREGROUND;
10319        }
10320        if (r.startRequested) {
10321            info.flags |= ActivityManager.RunningServiceInfo.FLAG_STARTED;
10322        }
10323        if (r.app != null && r.app.pid == Process.myPid()) {
10324            info.flags |= ActivityManager.RunningServiceInfo.FLAG_SYSTEM_PROCESS;
10325        }
10326        if (r.app != null && r.app.persistent) {
10327            info.flags |= ActivityManager.RunningServiceInfo.FLAG_PERSISTENT_PROCESS;
10328        }
10329        for (ConnectionRecord conn : r.connections.values()) {
10330            if (conn.clientLabel != 0) {
10331                info.clientPackage = conn.binding.client.info.packageName;
10332                info.clientLabel = conn.clientLabel;
10333                break;
10334            }
10335        }
10336        return info;
10337    }
10338
10339    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
10340            int flags) {
10341        synchronized (this) {
10342            ArrayList<ActivityManager.RunningServiceInfo> res
10343                    = new ArrayList<ActivityManager.RunningServiceInfo>();
10344
10345            if (mServices.size() > 0) {
10346                Iterator<ServiceRecord> it = mServices.values().iterator();
10347                while (it.hasNext() && res.size() < maxNum) {
10348                    res.add(makeRunningServiceInfoLocked(it.next()));
10349                }
10350            }
10351
10352            for (int i=0; i<mRestartingServices.size() && res.size() < maxNum; i++) {
10353                ServiceRecord r = mRestartingServices.get(i);
10354                ActivityManager.RunningServiceInfo info =
10355                        makeRunningServiceInfoLocked(r);
10356                info.restarting = r.nextRestartTime;
10357                res.add(info);
10358            }
10359
10360            return res;
10361        }
10362    }
10363
10364    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
10365        synchronized (this) {
10366            ServiceRecord r = mServices.get(name);
10367            if (r != null) {
10368                for (ConnectionRecord conn : r.connections.values()) {
10369                    if (conn.clientIntent != null) {
10370                        return conn.clientIntent;
10371                    }
10372                }
10373            }
10374        }
10375        return null;
10376    }
10377
10378    private final ServiceRecord findServiceLocked(ComponentName name,
10379            IBinder token) {
10380        ServiceRecord r = mServices.get(name);
10381        return r == token ? r : null;
10382    }
10383
10384    private final class ServiceLookupResult {
10385        final ServiceRecord record;
10386        final String permission;
10387
10388        ServiceLookupResult(ServiceRecord _record, String _permission) {
10389            record = _record;
10390            permission = _permission;
10391        }
10392    };
10393
10394    private ServiceLookupResult findServiceLocked(Intent service,
10395            String resolvedType) {
10396        ServiceRecord r = null;
10397        if (service.getComponent() != null) {
10398            r = mServices.get(service.getComponent());
10399        }
10400        if (r == null) {
10401            Intent.FilterComparison filter = new Intent.FilterComparison(service);
10402            r = mServicesByIntent.get(filter);
10403        }
10404
10405        if (r == null) {
10406            try {
10407                ResolveInfo rInfo =
10408                    ActivityThread.getPackageManager().resolveService(
10409                            service, resolvedType, 0);
10410                ServiceInfo sInfo =
10411                    rInfo != null ? rInfo.serviceInfo : null;
10412                if (sInfo == null) {
10413                    return null;
10414                }
10415
10416                ComponentName name = new ComponentName(
10417                        sInfo.applicationInfo.packageName, sInfo.name);
10418                r = mServices.get(name);
10419            } catch (RemoteException ex) {
10420                // pm is in same process, this will never happen.
10421            }
10422        }
10423        if (r != null) {
10424            int callingPid = Binder.getCallingPid();
10425            int callingUid = Binder.getCallingUid();
10426            if (checkComponentPermission(r.permission,
10427                    callingPid, callingUid, r.exported ? -1 : r.appInfo.uid)
10428                    != PackageManager.PERMISSION_GRANTED) {
10429                Log.w(TAG, "Permission Denial: Accessing service " + r.name
10430                        + " from pid=" + callingPid
10431                        + ", uid=" + callingUid
10432                        + " requires " + r.permission);
10433                return new ServiceLookupResult(null, r.permission);
10434            }
10435            return new ServiceLookupResult(r, null);
10436        }
10437        return null;
10438    }
10439
10440    private class ServiceRestarter implements Runnable {
10441        private ServiceRecord mService;
10442
10443        void setService(ServiceRecord service) {
10444            mService = service;
10445        }
10446
10447        public void run() {
10448            synchronized(ActivityManagerService.this) {
10449                performServiceRestartLocked(mService);
10450            }
10451        }
10452    }
10453
10454    private ServiceLookupResult retrieveServiceLocked(Intent service,
10455            String resolvedType, int callingPid, int callingUid) {
10456        ServiceRecord r = null;
10457        if (service.getComponent() != null) {
10458            r = mServices.get(service.getComponent());
10459        }
10460        Intent.FilterComparison filter = new Intent.FilterComparison(service);
10461        r = mServicesByIntent.get(filter);
10462        if (r == null) {
10463            try {
10464                ResolveInfo rInfo =
10465                    ActivityThread.getPackageManager().resolveService(
10466                            service, resolvedType, STOCK_PM_FLAGS);
10467                ServiceInfo sInfo =
10468                    rInfo != null ? rInfo.serviceInfo : null;
10469                if (sInfo == null) {
10470                    Log.w(TAG, "Unable to start service " + service +
10471                          ": not found");
10472                    return null;
10473                }
10474
10475                ComponentName name = new ComponentName(
10476                        sInfo.applicationInfo.packageName, sInfo.name);
10477                r = mServices.get(name);
10478                if (r == null) {
10479                    filter = new Intent.FilterComparison(service.cloneFilter());
10480                    ServiceRestarter res = new ServiceRestarter();
10481                    BatteryStatsImpl.Uid.Pkg.Serv ss = null;
10482                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10483                    synchronized (stats) {
10484                        ss = stats.getServiceStatsLocked(
10485                                sInfo.applicationInfo.uid, sInfo.packageName,
10486                                sInfo.name);
10487                    }
10488                    r = new ServiceRecord(ss, name, filter, sInfo, res);
10489                    res.setService(r);
10490                    mServices.put(name, r);
10491                    mServicesByIntent.put(filter, r);
10492
10493                    // Make sure this component isn't in the pending list.
10494                    int N = mPendingServices.size();
10495                    for (int i=0; i<N; i++) {
10496                        ServiceRecord pr = mPendingServices.get(i);
10497                        if (pr.name.equals(name)) {
10498                            mPendingServices.remove(i);
10499                            i--;
10500                            N--;
10501                        }
10502                    }
10503                }
10504            } catch (RemoteException ex) {
10505                // pm is in same process, this will never happen.
10506            }
10507        }
10508        if (r != null) {
10509            if (checkComponentPermission(r.permission,
10510                    callingPid, callingUid, r.exported ? -1 : r.appInfo.uid)
10511                    != PackageManager.PERMISSION_GRANTED) {
10512                Log.w(TAG, "Permission Denial: Accessing service " + r.name
10513                        + " from pid=" + Binder.getCallingPid()
10514                        + ", uid=" + Binder.getCallingUid()
10515                        + " requires " + r.permission);
10516                return new ServiceLookupResult(null, r.permission);
10517            }
10518            return new ServiceLookupResult(r, null);
10519        }
10520        return null;
10521    }
10522
10523    private final void bumpServiceExecutingLocked(ServiceRecord r) {
10524        long now = SystemClock.uptimeMillis();
10525        if (r.executeNesting == 0 && r.app != null) {
10526            if (r.app.executingServices.size() == 0) {
10527                Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
10528                msg.obj = r.app;
10529                mHandler.sendMessageAtTime(msg, now+SERVICE_TIMEOUT);
10530            }
10531            r.app.executingServices.add(r);
10532        }
10533        r.executeNesting++;
10534        r.executingStart = now;
10535    }
10536
10537    private final void sendServiceArgsLocked(ServiceRecord r,
10538            boolean oomAdjusted) {
10539        final int N = r.pendingStarts.size();
10540        if (N == 0) {
10541            return;
10542        }
10543
10544        int i = 0;
10545        while (i < N) {
10546            try {
10547                ServiceRecord.StartItem si = r.pendingStarts.get(i);
10548                if (DEBUG_SERVICE) Log.v(TAG, "Sending arguments to service: "
10549                        + r.name + " " + r.intent + " args=" + si.intent);
10550                if (si.intent == null && N > 1) {
10551                    // If somehow we got a dummy start at the front, then
10552                    // just drop it here.
10553                    i++;
10554                    continue;
10555                }
10556                bumpServiceExecutingLocked(r);
10557                if (!oomAdjusted) {
10558                    oomAdjusted = true;
10559                    updateOomAdjLocked(r.app);
10560                }
10561                int flags = 0;
10562                if (si.deliveryCount > 0) {
10563                    flags |= Service.START_FLAG_RETRY;
10564                }
10565                if (si.doneExecutingCount > 0) {
10566                    flags |= Service.START_FLAG_REDELIVERY;
10567                }
10568                r.app.thread.scheduleServiceArgs(r, si.id, flags, si.intent);
10569                si.deliveredTime = SystemClock.uptimeMillis();
10570                r.deliveredStarts.add(si);
10571                si.deliveryCount++;
10572                i++;
10573            } catch (RemoteException e) {
10574                // Remote process gone...  we'll let the normal cleanup take
10575                // care of this.
10576                break;
10577            } catch (Exception e) {
10578                Log.w(TAG, "Unexpected exception", e);
10579                break;
10580            }
10581        }
10582        if (i == N) {
10583            r.pendingStarts.clear();
10584        } else {
10585            while (i > 0) {
10586                i--;
10587                r.pendingStarts.remove(i);
10588            }
10589        }
10590    }
10591
10592    private final boolean requestServiceBindingLocked(ServiceRecord r,
10593            IntentBindRecord i, boolean rebind) {
10594        if (r.app == null || r.app.thread == null) {
10595            // If service is not currently running, can't yet bind.
10596            return false;
10597        }
10598        if ((!i.requested || rebind) && i.apps.size() > 0) {
10599            try {
10600                bumpServiceExecutingLocked(r);
10601                if (DEBUG_SERVICE) Log.v(TAG, "Connecting binding " + i
10602                        + ": shouldUnbind=" + i.hasBound);
10603                r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind);
10604                if (!rebind) {
10605                    i.requested = true;
10606                }
10607                i.hasBound = true;
10608                i.doRebind = false;
10609            } catch (RemoteException e) {
10610                return false;
10611            }
10612        }
10613        return true;
10614    }
10615
10616    private final void requestServiceBindingsLocked(ServiceRecord r) {
10617        Iterator<IntentBindRecord> bindings = r.bindings.values().iterator();
10618        while (bindings.hasNext()) {
10619            IntentBindRecord i = bindings.next();
10620            if (!requestServiceBindingLocked(r, i, false)) {
10621                break;
10622            }
10623        }
10624    }
10625
10626    private final void realStartServiceLocked(ServiceRecord r,
10627            ProcessRecord app) throws RemoteException {
10628        if (app.thread == null) {
10629            throw new RemoteException();
10630        }
10631
10632        r.app = app;
10633        r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
10634
10635        app.services.add(r);
10636        bumpServiceExecutingLocked(r);
10637        updateLruProcessLocked(app, true, true);
10638
10639        boolean created = false;
10640        try {
10641            if (DEBUG_SERVICE) Log.v(TAG, "Scheduling start service: "
10642                    + r.name + " " + r.intent);
10643            mStringBuilder.setLength(0);
10644            r.intent.getIntent().toShortString(mStringBuilder, false, true);
10645            EventLog.writeEvent(EventLogTags.AM_CREATE_SERVICE,
10646                    System.identityHashCode(r), r.shortName,
10647                    mStringBuilder.toString(), r.app.pid);
10648            synchronized (r.stats.getBatteryStats()) {
10649                r.stats.startLaunchedLocked();
10650            }
10651            ensurePackageDexOpt(r.serviceInfo.packageName);
10652            app.thread.scheduleCreateService(r, r.serviceInfo);
10653            r.postNotification();
10654            created = true;
10655        } finally {
10656            if (!created) {
10657                app.services.remove(r);
10658                scheduleServiceRestartLocked(r, false);
10659            }
10660        }
10661
10662        requestServiceBindingsLocked(r);
10663
10664        // If the service is in the started state, and there are no
10665        // pending arguments, then fake up one so its onStartCommand() will
10666        // be called.
10667        if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
10668            r.lastStartId++;
10669            if (r.lastStartId < 1) {
10670                r.lastStartId = 1;
10671            }
10672            r.pendingStarts.add(new ServiceRecord.StartItem(r.lastStartId, null));
10673        }
10674
10675        sendServiceArgsLocked(r, true);
10676    }
10677
10678    private final boolean scheduleServiceRestartLocked(ServiceRecord r,
10679            boolean allowCancel) {
10680        boolean canceled = false;
10681
10682        final long now = SystemClock.uptimeMillis();
10683        long minDuration = SERVICE_RESTART_DURATION;
10684        long resetTime = SERVICE_RESET_RUN_DURATION;
10685
10686        // Any delivered but not yet finished starts should be put back
10687        // on the pending list.
10688        final int N = r.deliveredStarts.size();
10689        if (N > 0) {
10690            for (int i=N-1; i>=0; i--) {
10691                ServiceRecord.StartItem si = r.deliveredStarts.get(i);
10692                if (si.intent == null) {
10693                    // We'll generate this again if needed.
10694                } else if (!allowCancel || (si.deliveryCount < ServiceRecord.MAX_DELIVERY_COUNT
10695                        && si.doneExecutingCount < ServiceRecord.MAX_DONE_EXECUTING_COUNT)) {
10696                    r.pendingStarts.add(0, si);
10697                    long dur = SystemClock.uptimeMillis() - si.deliveredTime;
10698                    dur *= 2;
10699                    if (minDuration < dur) minDuration = dur;
10700                    if (resetTime < dur) resetTime = dur;
10701                } else {
10702                    Log.w(TAG, "Canceling start item " + si.intent + " in service "
10703                            + r.name);
10704                    canceled = true;
10705                }
10706            }
10707            r.deliveredStarts.clear();
10708        }
10709
10710        r.totalRestartCount++;
10711        if (r.restartDelay == 0) {
10712            r.restartCount++;
10713            r.restartDelay = minDuration;
10714        } else {
10715            // If it has been a "reasonably long time" since the service
10716            // was started, then reset our restart duration back to
10717            // the beginning, so we don't infinitely increase the duration
10718            // on a service that just occasionally gets killed (which is
10719            // a normal case, due to process being killed to reclaim memory).
10720            if (now > (r.restartTime+resetTime)) {
10721                r.restartCount = 1;
10722                r.restartDelay = minDuration;
10723            } else {
10724                r.restartDelay *= SERVICE_RESTART_DURATION_FACTOR;
10725                if (r.restartDelay < minDuration) {
10726                    r.restartDelay = minDuration;
10727                }
10728            }
10729        }
10730
10731        r.nextRestartTime = now + r.restartDelay;
10732
10733        // Make sure that we don't end up restarting a bunch of services
10734        // all at the same time.
10735        boolean repeat;
10736        do {
10737            repeat = false;
10738            for (int i=mRestartingServices.size()-1; i>=0; i--) {
10739                ServiceRecord r2 = mRestartingServices.get(i);
10740                if (r2 != r && r.nextRestartTime
10741                        >= (r2.nextRestartTime-SERVICE_MIN_RESTART_TIME_BETWEEN)
10742                        && r.nextRestartTime
10743                        < (r2.nextRestartTime+SERVICE_MIN_RESTART_TIME_BETWEEN)) {
10744                    r.nextRestartTime = r2.nextRestartTime + SERVICE_MIN_RESTART_TIME_BETWEEN;
10745                    r.restartDelay = r.nextRestartTime - now;
10746                    repeat = true;
10747                    break;
10748                }
10749            }
10750        } while (repeat);
10751
10752        if (!mRestartingServices.contains(r)) {
10753            mRestartingServices.add(r);
10754        }
10755
10756        r.cancelNotification();
10757
10758        mHandler.removeCallbacks(r.restarter);
10759        mHandler.postAtTime(r.restarter, r.nextRestartTime);
10760        r.nextRestartTime = SystemClock.uptimeMillis() + r.restartDelay;
10761        Log.w(TAG, "Scheduling restart of crashed service "
10762                + r.shortName + " in " + r.restartDelay + "ms");
10763        EventLog.writeEvent(EventLogTags.AM_SCHEDULE_SERVICE_RESTART,
10764                r.shortName, r.restartDelay);
10765
10766        Message msg = Message.obtain();
10767        msg.what = SERVICE_ERROR_MSG;
10768        msg.obj = r;
10769        mHandler.sendMessage(msg);
10770
10771        return canceled;
10772    }
10773
10774    final void performServiceRestartLocked(ServiceRecord r) {
10775        if (!mRestartingServices.contains(r)) {
10776            return;
10777        }
10778        bringUpServiceLocked(r, r.intent.getIntent().getFlags(), true);
10779    }
10780
10781    private final boolean unscheduleServiceRestartLocked(ServiceRecord r) {
10782        if (r.restartDelay == 0) {
10783            return false;
10784        }
10785        r.resetRestartCounter();
10786        mRestartingServices.remove(r);
10787        mHandler.removeCallbacks(r.restarter);
10788        return true;
10789    }
10790
10791    private final boolean bringUpServiceLocked(ServiceRecord r,
10792            int intentFlags, boolean whileRestarting) {
10793        //Log.i(TAG, "Bring up service:");
10794        //r.dump("  ");
10795
10796        if (r.app != null && r.app.thread != null) {
10797            sendServiceArgsLocked(r, false);
10798            return true;
10799        }
10800
10801        if (!whileRestarting && r.restartDelay > 0) {
10802            // If waiting for a restart, then do nothing.
10803            return true;
10804        }
10805
10806        if (DEBUG_SERVICE) Log.v(TAG, "Bringing up service " + r.name
10807                + " " + r.intent);
10808
10809        // We are now bringing the service up, so no longer in the
10810        // restarting state.
10811        mRestartingServices.remove(r);
10812
10813        final String appName = r.processName;
10814        ProcessRecord app = getProcessRecordLocked(appName, r.appInfo.uid);
10815        if (app != null && app.thread != null) {
10816            try {
10817                realStartServiceLocked(r, app);
10818                return true;
10819            } catch (RemoteException e) {
10820                Log.w(TAG, "Exception when starting service " + r.shortName, e);
10821            }
10822
10823            // If a dead object exception was thrown -- fall through to
10824            // restart the application.
10825        }
10826
10827        // Not running -- get it started, and enqueue this service record
10828        // to be executed when the app comes up.
10829        if (startProcessLocked(appName, r.appInfo, true, intentFlags,
10830                "service", r.name, false) == null) {
10831            Log.w(TAG, "Unable to launch app "
10832                    + r.appInfo.packageName + "/"
10833                    + r.appInfo.uid + " for service "
10834                    + r.intent.getIntent() + ": process is bad");
10835            bringDownServiceLocked(r, true);
10836            return false;
10837        }
10838
10839        if (!mPendingServices.contains(r)) {
10840            mPendingServices.add(r);
10841        }
10842
10843        return true;
10844    }
10845
10846    private final void bringDownServiceLocked(ServiceRecord r, boolean force) {
10847        //Log.i(TAG, "Bring down service:");
10848        //r.dump("  ");
10849
10850        // Does it still need to run?
10851        if (!force && r.startRequested) {
10852            return;
10853        }
10854        if (r.connections.size() > 0) {
10855            if (!force) {
10856                // XXX should probably keep a count of the number of auto-create
10857                // connections directly in the service.
10858                Iterator<ConnectionRecord> it = r.connections.values().iterator();
10859                while (it.hasNext()) {
10860                    ConnectionRecord cr = it.next();
10861                    if ((cr.flags&Context.BIND_AUTO_CREATE) != 0) {
10862                        return;
10863                    }
10864                }
10865            }
10866
10867            // Report to all of the connections that the service is no longer
10868            // available.
10869            Iterator<ConnectionRecord> it = r.connections.values().iterator();
10870            while (it.hasNext()) {
10871                ConnectionRecord c = it.next();
10872                try {
10873                    // todo: shouldn't be a synchronous call!
10874                    c.conn.connected(r.name, null);
10875                } catch (Exception e) {
10876                    Log.w(TAG, "Failure disconnecting service " + r.name +
10877                          " to connection " + c.conn.asBinder() +
10878                          " (in " + c.binding.client.processName + ")", e);
10879                }
10880            }
10881        }
10882
10883        // Tell the service that it has been unbound.
10884        if (r.bindings.size() > 0 && r.app != null && r.app.thread != null) {
10885            Iterator<IntentBindRecord> it = r.bindings.values().iterator();
10886            while (it.hasNext()) {
10887                IntentBindRecord ibr = it.next();
10888                if (DEBUG_SERVICE) Log.v(TAG, "Bringing down binding " + ibr
10889                        + ": hasBound=" + ibr.hasBound);
10890                if (r.app != null && r.app.thread != null && ibr.hasBound) {
10891                    try {
10892                        bumpServiceExecutingLocked(r);
10893                        updateOomAdjLocked(r.app);
10894                        ibr.hasBound = false;
10895                        r.app.thread.scheduleUnbindService(r,
10896                                ibr.intent.getIntent());
10897                    } catch (Exception e) {
10898                        Log.w(TAG, "Exception when unbinding service "
10899                                + r.shortName, e);
10900                        serviceDoneExecutingLocked(r, true);
10901                    }
10902                }
10903            }
10904        }
10905
10906        if (DEBUG_SERVICE) Log.v(TAG, "Bringing down service " + r.name
10907                 + " " + r.intent);
10908        EventLog.writeEvent(EventLogTags.AM_DESTROY_SERVICE,
10909                System.identityHashCode(r), r.shortName,
10910                (r.app != null) ? r.app.pid : -1);
10911
10912        mServices.remove(r.name);
10913        mServicesByIntent.remove(r.intent);
10914        if (localLOGV) Log.v(TAG, "BRING DOWN SERVICE: " + r.shortName);
10915        r.totalRestartCount = 0;
10916        unscheduleServiceRestartLocked(r);
10917
10918        // Also make sure it is not on the pending list.
10919        int N = mPendingServices.size();
10920        for (int i=0; i<N; i++) {
10921            if (mPendingServices.get(i) == r) {
10922                mPendingServices.remove(i);
10923                if (DEBUG_SERVICE) Log.v(
10924                    TAG, "Removed pending service: " + r.shortName);
10925                i--;
10926                N--;
10927            }
10928        }
10929
10930        r.cancelNotification();
10931        r.isForeground = false;
10932        r.foregroundId = 0;
10933        r.foregroundNoti = null;
10934
10935        // Clear start entries.
10936        r.deliveredStarts.clear();
10937        r.pendingStarts.clear();
10938
10939        if (r.app != null) {
10940            synchronized (r.stats.getBatteryStats()) {
10941                r.stats.stopLaunchedLocked();
10942            }
10943            r.app.services.remove(r);
10944            if (r.app.thread != null) {
10945                try {
10946                    if (DEBUG_SERVICE) Log.v(TAG,
10947                            "Stopping service: " + r.shortName);
10948                    bumpServiceExecutingLocked(r);
10949                    mStoppingServices.add(r);
10950                    updateOomAdjLocked(r.app);
10951                    r.app.thread.scheduleStopService(r);
10952                } catch (Exception e) {
10953                    Log.w(TAG, "Exception when stopping service "
10954                            + r.shortName, e);
10955                    serviceDoneExecutingLocked(r, true);
10956                }
10957                updateServiceForegroundLocked(r.app, false);
10958            } else {
10959                if (DEBUG_SERVICE) Log.v(
10960                    TAG, "Removed service that has no process: " + r.shortName);
10961            }
10962        } else {
10963            if (DEBUG_SERVICE) Log.v(
10964                TAG, "Removed service that is not running: " + r.shortName);
10965        }
10966    }
10967
10968    ComponentName startServiceLocked(IApplicationThread caller,
10969            Intent service, String resolvedType,
10970            int callingPid, int callingUid) {
10971        synchronized(this) {
10972            if (DEBUG_SERVICE) Log.v(TAG, "startService: " + service
10973                    + " type=" + resolvedType + " args=" + service.getExtras());
10974
10975            if (caller != null) {
10976                final ProcessRecord callerApp = getRecordForAppLocked(caller);
10977                if (callerApp == null) {
10978                    throw new SecurityException(
10979                            "Unable to find app for caller " + caller
10980                            + " (pid=" + Binder.getCallingPid()
10981                            + ") when starting service " + service);
10982                }
10983            }
10984
10985            ServiceLookupResult res =
10986                retrieveServiceLocked(service, resolvedType,
10987                        callingPid, callingUid);
10988            if (res == null) {
10989                return null;
10990            }
10991            if (res.record == null) {
10992                return new ComponentName("!", res.permission != null
10993                        ? res.permission : "private to package");
10994            }
10995            ServiceRecord r = res.record;
10996            if (unscheduleServiceRestartLocked(r)) {
10997                if (DEBUG_SERVICE) Log.v(TAG, "START SERVICE WHILE RESTART PENDING: "
10998                        + r.shortName);
10999            }
11000            r.startRequested = true;
11001            r.callStart = false;
11002            r.lastStartId++;
11003            if (r.lastStartId < 1) {
11004                r.lastStartId = 1;
11005            }
11006            r.pendingStarts.add(new ServiceRecord.StartItem(r.lastStartId, service));
11007            r.lastActivity = SystemClock.uptimeMillis();
11008            synchronized (r.stats.getBatteryStats()) {
11009                r.stats.startRunningLocked();
11010            }
11011            if (!bringUpServiceLocked(r, service.getFlags(), false)) {
11012                return new ComponentName("!", "Service process is bad");
11013            }
11014            return r.name;
11015        }
11016    }
11017
11018    public ComponentName startService(IApplicationThread caller, Intent service,
11019            String resolvedType) {
11020        // Refuse possible leaked file descriptors
11021        if (service != null && service.hasFileDescriptors() == true) {
11022            throw new IllegalArgumentException("File descriptors passed in Intent");
11023        }
11024
11025        synchronized(this) {
11026            final int callingPid = Binder.getCallingPid();
11027            final int callingUid = Binder.getCallingUid();
11028            final long origId = Binder.clearCallingIdentity();
11029            ComponentName res = startServiceLocked(caller, service,
11030                    resolvedType, callingPid, callingUid);
11031            Binder.restoreCallingIdentity(origId);
11032            return res;
11033        }
11034    }
11035
11036    ComponentName startServiceInPackage(int uid,
11037            Intent service, String resolvedType) {
11038        synchronized(this) {
11039            final long origId = Binder.clearCallingIdentity();
11040            ComponentName res = startServiceLocked(null, service,
11041                    resolvedType, -1, uid);
11042            Binder.restoreCallingIdentity(origId);
11043            return res;
11044        }
11045    }
11046
11047    public int stopService(IApplicationThread caller, Intent service,
11048            String resolvedType) {
11049        // Refuse possible leaked file descriptors
11050        if (service != null && service.hasFileDescriptors() == true) {
11051            throw new IllegalArgumentException("File descriptors passed in Intent");
11052        }
11053
11054        synchronized(this) {
11055            if (DEBUG_SERVICE) Log.v(TAG, "stopService: " + service
11056                    + " type=" + resolvedType);
11057
11058            final ProcessRecord callerApp = getRecordForAppLocked(caller);
11059            if (caller != null && callerApp == null) {
11060                throw new SecurityException(
11061                        "Unable to find app for caller " + caller
11062                        + " (pid=" + Binder.getCallingPid()
11063                        + ") when stopping service " + service);
11064            }
11065
11066            // If this service is active, make sure it is stopped.
11067            ServiceLookupResult r = findServiceLocked(service, resolvedType);
11068            if (r != null) {
11069                if (r.record != null) {
11070                    synchronized (r.record.stats.getBatteryStats()) {
11071                        r.record.stats.stopRunningLocked();
11072                    }
11073                    r.record.startRequested = false;
11074                    r.record.callStart = false;
11075                    final long origId = Binder.clearCallingIdentity();
11076                    bringDownServiceLocked(r.record, false);
11077                    Binder.restoreCallingIdentity(origId);
11078                    return 1;
11079                }
11080                return -1;
11081            }
11082        }
11083
11084        return 0;
11085    }
11086
11087    public IBinder peekService(Intent service, String resolvedType) {
11088        // Refuse possible leaked file descriptors
11089        if (service != null && service.hasFileDescriptors() == true) {
11090            throw new IllegalArgumentException("File descriptors passed in Intent");
11091        }
11092
11093        IBinder ret = null;
11094
11095        synchronized(this) {
11096            ServiceLookupResult r = findServiceLocked(service, resolvedType);
11097
11098            if (r != null) {
11099                // r.record is null if findServiceLocked() failed the caller permission check
11100                if (r.record == null) {
11101                    throw new SecurityException(
11102                            "Permission Denial: Accessing service " + r.record.name
11103                            + " from pid=" + Binder.getCallingPid()
11104                            + ", uid=" + Binder.getCallingUid()
11105                            + " requires " + r.permission);
11106                }
11107                IntentBindRecord ib = r.record.bindings.get(r.record.intent);
11108                if (ib != null) {
11109                    ret = ib.binder;
11110                }
11111            }
11112        }
11113
11114        return ret;
11115    }
11116
11117    public boolean stopServiceToken(ComponentName className, IBinder token,
11118            int startId) {
11119        synchronized(this) {
11120            if (DEBUG_SERVICE) Log.v(TAG, "stopServiceToken: " + className
11121                    + " " + token + " startId=" + startId);
11122            ServiceRecord r = findServiceLocked(className, token);
11123            if (r != null) {
11124                if (startId >= 0) {
11125                    // Asked to only stop if done with all work.  Note that
11126                    // to avoid leaks, we will take this as dropping all
11127                    // start items up to and including this one.
11128                    ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
11129                    if (si != null) {
11130                        while (r.deliveredStarts.size() > 0) {
11131                            if (r.deliveredStarts.remove(0) == si) {
11132                                break;
11133                            }
11134                        }
11135                    }
11136
11137                    if (r.lastStartId != startId) {
11138                        return false;
11139                    }
11140
11141                    if (r.deliveredStarts.size() > 0) {
11142                        Log.w(TAG, "stopServiceToken startId " + startId
11143                                + " is last, but have " + r.deliveredStarts.size()
11144                                + " remaining args");
11145                    }
11146                }
11147
11148                synchronized (r.stats.getBatteryStats()) {
11149                    r.stats.stopRunningLocked();
11150                    r.startRequested = false;
11151                    r.callStart = false;
11152                }
11153                final long origId = Binder.clearCallingIdentity();
11154                bringDownServiceLocked(r, false);
11155                Binder.restoreCallingIdentity(origId);
11156                return true;
11157            }
11158        }
11159        return false;
11160    }
11161
11162    public void setServiceForeground(ComponentName className, IBinder token,
11163            int id, Notification notification, boolean removeNotification) {
11164        final long origId = Binder.clearCallingIdentity();
11165        try {
11166        synchronized(this) {
11167            ServiceRecord r = findServiceLocked(className, token);
11168            if (r != null) {
11169                if (id != 0) {
11170                    if (notification == null) {
11171                        throw new IllegalArgumentException("null notification");
11172                    }
11173                    if (r.foregroundId != id) {
11174                        r.cancelNotification();
11175                        r.foregroundId = id;
11176                    }
11177                    notification.flags |= Notification.FLAG_FOREGROUND_SERVICE;
11178                    r.foregroundNoti = notification;
11179                    r.isForeground = true;
11180                    r.postNotification();
11181                    if (r.app != null) {
11182                        updateServiceForegroundLocked(r.app, true);
11183                    }
11184                } else {
11185                    if (r.isForeground) {
11186                        r.isForeground = false;
11187                        if (r.app != null) {
11188                            updateServiceForegroundLocked(r.app, true);
11189                        }
11190                    }
11191                    if (removeNotification) {
11192                        r.cancelNotification();
11193                        r.foregroundId = 0;
11194                        r.foregroundNoti = null;
11195                    }
11196                }
11197            }
11198        }
11199        } finally {
11200            Binder.restoreCallingIdentity(origId);
11201        }
11202    }
11203
11204    public void updateServiceForegroundLocked(ProcessRecord proc, boolean oomAdj) {
11205        boolean anyForeground = false;
11206        for (ServiceRecord sr : (HashSet<ServiceRecord>)proc.services) {
11207            if (sr.isForeground) {
11208                anyForeground = true;
11209                break;
11210            }
11211        }
11212        if (anyForeground != proc.foregroundServices) {
11213            proc.foregroundServices = anyForeground;
11214            if (oomAdj) {
11215                updateOomAdjLocked();
11216            }
11217        }
11218    }
11219
11220    public int bindService(IApplicationThread caller, IBinder token,
11221            Intent service, String resolvedType,
11222            IServiceConnection connection, int flags) {
11223        // Refuse possible leaked file descriptors
11224        if (service != null && service.hasFileDescriptors() == true) {
11225            throw new IllegalArgumentException("File descriptors passed in Intent");
11226        }
11227
11228        synchronized(this) {
11229            if (DEBUG_SERVICE) Log.v(TAG, "bindService: " + service
11230                    + " type=" + resolvedType + " conn=" + connection.asBinder()
11231                    + " flags=0x" + Integer.toHexString(flags));
11232            final ProcessRecord callerApp = getRecordForAppLocked(caller);
11233            if (callerApp == null) {
11234                throw new SecurityException(
11235                        "Unable to find app for caller " + caller
11236                        + " (pid=" + Binder.getCallingPid()
11237                        + ") when binding service " + service);
11238            }
11239
11240            HistoryRecord activity = null;
11241            if (token != null) {
11242                int aindex = indexOfTokenLocked(token);
11243                if (aindex < 0) {
11244                    Log.w(TAG, "Binding with unknown activity: " + token);
11245                    return 0;
11246                }
11247                activity = (HistoryRecord)mHistory.get(aindex);
11248            }
11249
11250            int clientLabel = 0;
11251            PendingIntent clientIntent = null;
11252
11253            if (callerApp.info.uid == Process.SYSTEM_UID) {
11254                // Hacky kind of thing -- allow system stuff to tell us
11255                // what they are, so we can report this elsewhere for
11256                // others to know why certain services are running.
11257                try {
11258                    clientIntent = (PendingIntent)service.getParcelableExtra(
11259                            Intent.EXTRA_CLIENT_INTENT);
11260                } catch (RuntimeException e) {
11261                }
11262                if (clientIntent != null) {
11263                    clientLabel = service.getIntExtra(Intent.EXTRA_CLIENT_LABEL, 0);
11264                    if (clientLabel != 0) {
11265                        // There are no useful extras in the intent, trash them.
11266                        // System code calling with this stuff just needs to know
11267                        // this will happen.
11268                        service = service.cloneFilter();
11269                    }
11270                }
11271            }
11272
11273            ServiceLookupResult res =
11274                retrieveServiceLocked(service, resolvedType,
11275                        Binder.getCallingPid(), Binder.getCallingUid());
11276            if (res == null) {
11277                return 0;
11278            }
11279            if (res.record == null) {
11280                return -1;
11281            }
11282            ServiceRecord s = res.record;
11283
11284            final long origId = Binder.clearCallingIdentity();
11285
11286            if (unscheduleServiceRestartLocked(s)) {
11287                if (DEBUG_SERVICE) Log.v(TAG, "BIND SERVICE WHILE RESTART PENDING: "
11288                        + s.shortName);
11289            }
11290
11291            AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
11292            ConnectionRecord c = new ConnectionRecord(b, activity,
11293                    connection, flags, clientLabel, clientIntent);
11294
11295            IBinder binder = connection.asBinder();
11296            s.connections.put(binder, c);
11297            b.connections.add(c);
11298            if (activity != null) {
11299                if (activity.connections == null) {
11300                    activity.connections = new HashSet<ConnectionRecord>();
11301                }
11302                activity.connections.add(c);
11303            }
11304            b.client.connections.add(c);
11305            mServiceConnections.put(binder, c);
11306
11307            if ((flags&Context.BIND_AUTO_CREATE) != 0) {
11308                s.lastActivity = SystemClock.uptimeMillis();
11309                if (!bringUpServiceLocked(s, service.getFlags(), false)) {
11310                    return 0;
11311                }
11312            }
11313
11314            if (s.app != null) {
11315                // This could have made the service more important.
11316                updateOomAdjLocked(s.app);
11317            }
11318
11319            if (DEBUG_SERVICE) Log.v(TAG, "Bind " + s + " with " + b
11320                    + ": received=" + b.intent.received
11321                    + " apps=" + b.intent.apps.size()
11322                    + " doRebind=" + b.intent.doRebind);
11323
11324            if (s.app != null && b.intent.received) {
11325                // Service is already running, so we can immediately
11326                // publish the connection.
11327                try {
11328                    c.conn.connected(s.name, b.intent.binder);
11329                } catch (Exception e) {
11330                    Log.w(TAG, "Failure sending service " + s.shortName
11331                            + " to connection " + c.conn.asBinder()
11332                            + " (in " + c.binding.client.processName + ")", e);
11333                }
11334
11335                // If this is the first app connected back to this binding,
11336                // and the service had previously asked to be told when
11337                // rebound, then do so.
11338                if (b.intent.apps.size() == 1 && b.intent.doRebind) {
11339                    requestServiceBindingLocked(s, b.intent, true);
11340                }
11341            } else if (!b.intent.requested) {
11342                requestServiceBindingLocked(s, b.intent, false);
11343            }
11344
11345            Binder.restoreCallingIdentity(origId);
11346        }
11347
11348        return 1;
11349    }
11350
11351    private void removeConnectionLocked(
11352        ConnectionRecord c, ProcessRecord skipApp, HistoryRecord skipAct) {
11353        IBinder binder = c.conn.asBinder();
11354        AppBindRecord b = c.binding;
11355        ServiceRecord s = b.service;
11356        s.connections.remove(binder);
11357        b.connections.remove(c);
11358        if (c.activity != null && c.activity != skipAct) {
11359            if (c.activity.connections != null) {
11360                c.activity.connections.remove(c);
11361            }
11362        }
11363        if (b.client != skipApp) {
11364            b.client.connections.remove(c);
11365        }
11366        mServiceConnections.remove(binder);
11367
11368        if (b.connections.size() == 0) {
11369            b.intent.apps.remove(b.client);
11370        }
11371
11372        if (DEBUG_SERVICE) Log.v(TAG, "Disconnecting binding " + b.intent
11373                + ": shouldUnbind=" + b.intent.hasBound);
11374        if (s.app != null && s.app.thread != null && b.intent.apps.size() == 0
11375                && b.intent.hasBound) {
11376            try {
11377                bumpServiceExecutingLocked(s);
11378                updateOomAdjLocked(s.app);
11379                b.intent.hasBound = false;
11380                // Assume the client doesn't want to know about a rebind;
11381                // we will deal with that later if it asks for one.
11382                b.intent.doRebind = false;
11383                s.app.thread.scheduleUnbindService(s, b.intent.intent.getIntent());
11384            } catch (Exception e) {
11385                Log.w(TAG, "Exception when unbinding service " + s.shortName, e);
11386                serviceDoneExecutingLocked(s, true);
11387            }
11388        }
11389
11390        if ((c.flags&Context.BIND_AUTO_CREATE) != 0) {
11391            bringDownServiceLocked(s, false);
11392        }
11393    }
11394
11395    public boolean unbindService(IServiceConnection connection) {
11396        synchronized (this) {
11397            IBinder binder = connection.asBinder();
11398            if (DEBUG_SERVICE) Log.v(TAG, "unbindService: conn=" + binder);
11399            ConnectionRecord r = mServiceConnections.get(binder);
11400            if (r == null) {
11401                Log.w(TAG, "Unbind failed: could not find connection for "
11402                      + connection.asBinder());
11403                return false;
11404            }
11405
11406            final long origId = Binder.clearCallingIdentity();
11407
11408            removeConnectionLocked(r, null, null);
11409
11410            if (r.binding.service.app != null) {
11411                // This could have made the service less important.
11412                updateOomAdjLocked(r.binding.service.app);
11413            }
11414
11415            Binder.restoreCallingIdentity(origId);
11416        }
11417
11418        return true;
11419    }
11420
11421    public void publishService(IBinder token, Intent intent, IBinder service) {
11422        // Refuse possible leaked file descriptors
11423        if (intent != null && intent.hasFileDescriptors() == true) {
11424            throw new IllegalArgumentException("File descriptors passed in Intent");
11425        }
11426
11427        synchronized(this) {
11428            if (!(token instanceof ServiceRecord)) {
11429                throw new IllegalArgumentException("Invalid service token");
11430            }
11431            ServiceRecord r = (ServiceRecord)token;
11432
11433            final long origId = Binder.clearCallingIdentity();
11434
11435            if (DEBUG_SERVICE) Log.v(TAG, "PUBLISHING SERVICE " + r.name
11436                    + " " + intent + ": " + service);
11437            if (r != null) {
11438                Intent.FilterComparison filter
11439                        = new Intent.FilterComparison(intent);
11440                IntentBindRecord b = r.bindings.get(filter);
11441                if (b != null && !b.received) {
11442                    b.binder = service;
11443                    b.requested = true;
11444                    b.received = true;
11445                    if (r.connections.size() > 0) {
11446                        Iterator<ConnectionRecord> it
11447                                = r.connections.values().iterator();
11448                        while (it.hasNext()) {
11449                            ConnectionRecord c = it.next();
11450                            if (!filter.equals(c.binding.intent.intent)) {
11451                                if (DEBUG_SERVICE) Log.v(
11452                                        TAG, "Not publishing to: " + c);
11453                                if (DEBUG_SERVICE) Log.v(
11454                                        TAG, "Bound intent: " + c.binding.intent.intent);
11455                                if (DEBUG_SERVICE) Log.v(
11456                                        TAG, "Published intent: " + intent);
11457                                continue;
11458                            }
11459                            if (DEBUG_SERVICE) Log.v(TAG, "Publishing to: " + c);
11460                            try {
11461                                c.conn.connected(r.name, service);
11462                            } catch (Exception e) {
11463                                Log.w(TAG, "Failure sending service " + r.name +
11464                                      " to connection " + c.conn.asBinder() +
11465                                      " (in " + c.binding.client.processName + ")", e);
11466                            }
11467                        }
11468                    }
11469                }
11470
11471                serviceDoneExecutingLocked(r, mStoppingServices.contains(r));
11472
11473                Binder.restoreCallingIdentity(origId);
11474            }
11475        }
11476    }
11477
11478    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
11479        // Refuse possible leaked file descriptors
11480        if (intent != null && intent.hasFileDescriptors() == true) {
11481            throw new IllegalArgumentException("File descriptors passed in Intent");
11482        }
11483
11484        synchronized(this) {
11485            if (!(token instanceof ServiceRecord)) {
11486                throw new IllegalArgumentException("Invalid service token");
11487            }
11488            ServiceRecord r = (ServiceRecord)token;
11489
11490            final long origId = Binder.clearCallingIdentity();
11491
11492            if (r != null) {
11493                Intent.FilterComparison filter
11494                        = new Intent.FilterComparison(intent);
11495                IntentBindRecord b = r.bindings.get(filter);
11496                if (DEBUG_SERVICE) Log.v(TAG, "unbindFinished in " + r
11497                        + " at " + b + ": apps="
11498                        + (b != null ? b.apps.size() : 0));
11499                if (b != null) {
11500                    if (b.apps.size() > 0) {
11501                        // Applications have already bound since the last
11502                        // unbind, so just rebind right here.
11503                        requestServiceBindingLocked(r, b, true);
11504                    } else {
11505                        // Note to tell the service the next time there is
11506                        // a new client.
11507                        b.doRebind = true;
11508                    }
11509                }
11510
11511                serviceDoneExecutingLocked(r, mStoppingServices.contains(r));
11512
11513                Binder.restoreCallingIdentity(origId);
11514            }
11515        }
11516    }
11517
11518    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
11519        synchronized(this) {
11520            if (!(token instanceof ServiceRecord)) {
11521                throw new IllegalArgumentException("Invalid service token");
11522            }
11523            ServiceRecord r = (ServiceRecord)token;
11524            boolean inStopping = mStoppingServices.contains(token);
11525            if (r != null) {
11526                if (DEBUG_SERVICE) Log.v(TAG, "DONE EXECUTING SERVICE " + r.name
11527                        + ": nesting=" + r.executeNesting
11528                        + ", inStopping=" + inStopping);
11529                if (r != token) {
11530                    Log.w(TAG, "Done executing service " + r.name
11531                          + " with incorrect token: given " + token
11532                          + ", expected " + r);
11533                    return;
11534                }
11535
11536                if (type == 1) {
11537                    // This is a call from a service start...  take care of
11538                    // book-keeping.
11539                    r.callStart = true;
11540                    switch (res) {
11541                        case Service.START_STICKY_COMPATIBILITY:
11542                        case Service.START_STICKY: {
11543                            // We are done with the associated start arguments.
11544                            r.findDeliveredStart(startId, true);
11545                            // Don't stop if killed.
11546                            r.stopIfKilled = false;
11547                            break;
11548                        }
11549                        case Service.START_NOT_STICKY: {
11550                            // We are done with the associated start arguments.
11551                            r.findDeliveredStart(startId, true);
11552                            if (r.lastStartId == startId) {
11553                                // There is no more work, and this service
11554                                // doesn't want to hang around if killed.
11555                                r.stopIfKilled = true;
11556                            }
11557                            break;
11558                        }
11559                        case Service.START_REDELIVER_INTENT: {
11560                            // We'll keep this item until they explicitly
11561                            // call stop for it, but keep track of the fact
11562                            // that it was delivered.
11563                            ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
11564                            if (si != null) {
11565                                si.deliveryCount = 0;
11566                                si.doneExecutingCount++;
11567                                // Don't stop if killed.
11568                                r.stopIfKilled = true;
11569                            }
11570                            break;
11571                        }
11572                        default:
11573                            throw new IllegalArgumentException(
11574                                    "Unknown service start result: " + res);
11575                    }
11576                    if (res == Service.START_STICKY_COMPATIBILITY) {
11577                        r.callStart = false;
11578                    }
11579                }
11580
11581                final long origId = Binder.clearCallingIdentity();
11582                serviceDoneExecutingLocked(r, inStopping);
11583                Binder.restoreCallingIdentity(origId);
11584            } else {
11585                Log.w(TAG, "Done executing unknown service " + r.name
11586                        + " with token " + token);
11587            }
11588        }
11589    }
11590
11591    public void serviceDoneExecutingLocked(ServiceRecord r, boolean inStopping) {
11592        r.executeNesting--;
11593        if (r.executeNesting <= 0 && r.app != null) {
11594            r.app.executingServices.remove(r);
11595            if (r.app.executingServices.size() == 0) {
11596                mHandler.removeMessages(SERVICE_TIMEOUT_MSG, r.app);
11597            }
11598            if (inStopping) {
11599                mStoppingServices.remove(r);
11600            }
11601            updateOomAdjLocked(r.app);
11602        }
11603    }
11604
11605    void serviceTimeout(ProcessRecord proc) {
11606        synchronized(this) {
11607            if (proc.executingServices.size() == 0 || proc.thread == null) {
11608                return;
11609            }
11610            long maxTime = SystemClock.uptimeMillis() - SERVICE_TIMEOUT;
11611            Iterator<ServiceRecord> it = proc.executingServices.iterator();
11612            ServiceRecord timeout = null;
11613            long nextTime = 0;
11614            while (it.hasNext()) {
11615                ServiceRecord sr = it.next();
11616                if (sr.executingStart < maxTime) {
11617                    timeout = sr;
11618                    break;
11619                }
11620                if (sr.executingStart > nextTime) {
11621                    nextTime = sr.executingStart;
11622                }
11623            }
11624            if (timeout != null && mLruProcesses.contains(proc)) {
11625                Log.w(TAG, "Timeout executing service: " + timeout);
11626                appNotRespondingLocked(proc, null, null, "Executing service " + timeout.name);
11627            } else {
11628                Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
11629                msg.obj = proc;
11630                mHandler.sendMessageAtTime(msg, nextTime+SERVICE_TIMEOUT);
11631            }
11632        }
11633    }
11634
11635    // =========================================================
11636    // BACKUP AND RESTORE
11637    // =========================================================
11638
11639    // Cause the target app to be launched if necessary and its backup agent
11640    // instantiated.  The backup agent will invoke backupAgentCreated() on the
11641    // activity manager to announce its creation.
11642    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
11643        if (DEBUG_BACKUP) Log.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode);
11644        enforceCallingPermission("android.permission.BACKUP", "startBackupAgent");
11645
11646        synchronized(this) {
11647            // !!! TODO: currently no check here that we're already bound
11648            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
11649            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11650            synchronized (stats) {
11651                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
11652            }
11653
11654            BackupRecord r = new BackupRecord(ss, app, backupMode);
11655            ComponentName hostingName = new ComponentName(app.packageName, app.backupAgentName);
11656            // startProcessLocked() returns existing proc's record if it's already running
11657            ProcessRecord proc = startProcessLocked(app.processName, app,
11658                    false, 0, "backup", hostingName, false);
11659            if (proc == null) {
11660                Log.e(TAG, "Unable to start backup agent process " + r);
11661                return false;
11662            }
11663
11664            r.app = proc;
11665            mBackupTarget = r;
11666            mBackupAppName = app.packageName;
11667
11668            // Try not to kill the process during backup
11669            updateOomAdjLocked(proc);
11670
11671            // If the process is already attached, schedule the creation of the backup agent now.
11672            // If it is not yet live, this will be done when it attaches to the framework.
11673            if (proc.thread != null) {
11674                if (DEBUG_BACKUP) Log.v(TAG, "Agent proc already running: " + proc);
11675                try {
11676                    proc.thread.scheduleCreateBackupAgent(app, backupMode);
11677                } catch (RemoteException e) {
11678                    // Will time out on the backup manager side
11679                }
11680            } else {
11681                if (DEBUG_BACKUP) Log.v(TAG, "Agent proc not running, waiting for attach");
11682            }
11683            // Invariants: at this point, the target app process exists and the application
11684            // is either already running or in the process of coming up.  mBackupTarget and
11685            // mBackupAppName describe the app, so that when it binds back to the AM we
11686            // know that it's scheduled for a backup-agent operation.
11687        }
11688
11689        return true;
11690    }
11691
11692    // A backup agent has just come up
11693    public void backupAgentCreated(String agentPackageName, IBinder agent) {
11694        if (DEBUG_BACKUP) Log.v(TAG, "backupAgentCreated: " + agentPackageName
11695                + " = " + agent);
11696
11697        synchronized(this) {
11698            if (!agentPackageName.equals(mBackupAppName)) {
11699                Log.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
11700                return;
11701            }
11702
11703            long oldIdent = Binder.clearCallingIdentity();
11704            try {
11705                IBackupManager bm = IBackupManager.Stub.asInterface(
11706                        ServiceManager.getService(Context.BACKUP_SERVICE));
11707                bm.agentConnected(agentPackageName, agent);
11708            } catch (RemoteException e) {
11709                // can't happen; the backup manager service is local
11710            } catch (Exception e) {
11711                Log.w(TAG, "Exception trying to deliver BackupAgent binding: ");
11712                e.printStackTrace();
11713            } finally {
11714                Binder.restoreCallingIdentity(oldIdent);
11715            }
11716        }
11717    }
11718
11719    // done with this agent
11720    public void unbindBackupAgent(ApplicationInfo appInfo) {
11721        if (DEBUG_BACKUP) Log.v(TAG, "unbindBackupAgent: " + appInfo);
11722        if (appInfo == null) {
11723            Log.w(TAG, "unbind backup agent for null app");
11724            return;
11725        }
11726
11727        synchronized(this) {
11728            if (mBackupAppName == null) {
11729                Log.w(TAG, "Unbinding backup agent with no active backup");
11730                return;
11731            }
11732
11733            if (!mBackupAppName.equals(appInfo.packageName)) {
11734                Log.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
11735                return;
11736            }
11737
11738            ProcessRecord proc = mBackupTarget.app;
11739            mBackupTarget = null;
11740            mBackupAppName = null;
11741
11742            // Not backing this app up any more; reset its OOM adjustment
11743            updateOomAdjLocked(proc);
11744
11745            // If the app crashed during backup, 'thread' will be null here
11746            if (proc.thread != null) {
11747                try {
11748                    proc.thread.scheduleDestroyBackupAgent(appInfo);
11749                } catch (Exception e) {
11750                    Log.e(TAG, "Exception when unbinding backup agent:");
11751                    e.printStackTrace();
11752                }
11753            }
11754        }
11755    }
11756    // =========================================================
11757    // BROADCASTS
11758    // =========================================================
11759
11760    private final List getStickies(String action, IntentFilter filter,
11761            List cur) {
11762        final ContentResolver resolver = mContext.getContentResolver();
11763        final ArrayList<Intent> list = mStickyBroadcasts.get(action);
11764        if (list == null) {
11765            return cur;
11766        }
11767        int N = list.size();
11768        for (int i=0; i<N; i++) {
11769            Intent intent = list.get(i);
11770            if (filter.match(resolver, intent, true, TAG) >= 0) {
11771                if (cur == null) {
11772                    cur = new ArrayList<Intent>();
11773                }
11774                cur.add(intent);
11775            }
11776        }
11777        return cur;
11778    }
11779
11780    private final void scheduleBroadcastsLocked() {
11781        if (DEBUG_BROADCAST) Log.v(TAG, "Schedule broadcasts: current="
11782                + mBroadcastsScheduled);
11783
11784        if (mBroadcastsScheduled) {
11785            return;
11786        }
11787        mHandler.sendEmptyMessage(BROADCAST_INTENT_MSG);
11788        mBroadcastsScheduled = true;
11789    }
11790
11791    public Intent registerReceiver(IApplicationThread caller,
11792            IIntentReceiver receiver, IntentFilter filter, String permission) {
11793        synchronized(this) {
11794            ProcessRecord callerApp = null;
11795            if (caller != null) {
11796                callerApp = getRecordForAppLocked(caller);
11797                if (callerApp == null) {
11798                    throw new SecurityException(
11799                            "Unable to find app for caller " + caller
11800                            + " (pid=" + Binder.getCallingPid()
11801                            + ") when registering receiver " + receiver);
11802                }
11803            }
11804
11805            List allSticky = null;
11806
11807            // Look for any matching sticky broadcasts...
11808            Iterator actions = filter.actionsIterator();
11809            if (actions != null) {
11810                while (actions.hasNext()) {
11811                    String action = (String)actions.next();
11812                    allSticky = getStickies(action, filter, allSticky);
11813                }
11814            } else {
11815                allSticky = getStickies(null, filter, allSticky);
11816            }
11817
11818            // The first sticky in the list is returned directly back to
11819            // the client.
11820            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
11821
11822            if (DEBUG_BROADCAST) Log.v(TAG, "Register receiver " + filter
11823                    + ": " + sticky);
11824
11825            if (receiver == null) {
11826                return sticky;
11827            }
11828
11829            ReceiverList rl
11830                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11831            if (rl == null) {
11832                rl = new ReceiverList(this, callerApp,
11833                        Binder.getCallingPid(),
11834                        Binder.getCallingUid(), receiver);
11835                if (rl.app != null) {
11836                    rl.app.receivers.add(rl);
11837                } else {
11838                    try {
11839                        receiver.asBinder().linkToDeath(rl, 0);
11840                    } catch (RemoteException e) {
11841                        return sticky;
11842                    }
11843                    rl.linkedToDeath = true;
11844                }
11845                mRegisteredReceivers.put(receiver.asBinder(), rl);
11846            }
11847            BroadcastFilter bf = new BroadcastFilter(filter, rl, permission);
11848            rl.add(bf);
11849            if (!bf.debugCheck()) {
11850                Log.w(TAG, "==> For Dynamic broadast");
11851            }
11852            mReceiverResolver.addFilter(bf);
11853
11854            // Enqueue broadcasts for all existing stickies that match
11855            // this filter.
11856            if (allSticky != null) {
11857                ArrayList receivers = new ArrayList();
11858                receivers.add(bf);
11859
11860                int N = allSticky.size();
11861                for (int i=0; i<N; i++) {
11862                    Intent intent = (Intent)allSticky.get(i);
11863                    BroadcastRecord r = new BroadcastRecord(intent, null,
11864                            null, -1, -1, null, receivers, null, 0, null, null,
11865                            false, true, true);
11866                    if (mParallelBroadcasts.size() == 0) {
11867                        scheduleBroadcastsLocked();
11868                    }
11869                    mParallelBroadcasts.add(r);
11870                }
11871            }
11872
11873            return sticky;
11874        }
11875    }
11876
11877    public void unregisterReceiver(IIntentReceiver receiver) {
11878        if (DEBUG_BROADCAST) Log.v(TAG, "Unregister receiver: " + receiver);
11879
11880        boolean doNext = false;
11881
11882        synchronized(this) {
11883            ReceiverList rl
11884                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11885            if (rl != null) {
11886                if (rl.curBroadcast != null) {
11887                    BroadcastRecord r = rl.curBroadcast;
11888                    doNext = finishReceiverLocked(
11889                        receiver.asBinder(), r.resultCode, r.resultData,
11890                        r.resultExtras, r.resultAbort, true);
11891                }
11892
11893                if (rl.app != null) {
11894                    rl.app.receivers.remove(rl);
11895                }
11896                removeReceiverLocked(rl);
11897                if (rl.linkedToDeath) {
11898                    rl.linkedToDeath = false;
11899                    rl.receiver.asBinder().unlinkToDeath(rl, 0);
11900                }
11901            }
11902        }
11903
11904        if (!doNext) {
11905            return;
11906        }
11907
11908        final long origId = Binder.clearCallingIdentity();
11909        processNextBroadcast(false);
11910        trimApplications();
11911        Binder.restoreCallingIdentity(origId);
11912    }
11913
11914    void removeReceiverLocked(ReceiverList rl) {
11915        mRegisteredReceivers.remove(rl.receiver.asBinder());
11916        int N = rl.size();
11917        for (int i=0; i<N; i++) {
11918            mReceiverResolver.removeFilter(rl.get(i));
11919        }
11920    }
11921
11922    private final int broadcastIntentLocked(ProcessRecord callerApp,
11923            String callerPackage, Intent intent, String resolvedType,
11924            IIntentReceiver resultTo, int resultCode, String resultData,
11925            Bundle map, String requiredPermission,
11926            boolean ordered, boolean sticky, int callingPid, int callingUid) {
11927        intent = new Intent(intent);
11928
11929        if (DEBUG_BROADCAST_LIGHT) Log.v(
11930            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
11931            + " ordered=" + ordered);
11932        if ((resultTo != null) && !ordered) {
11933            Log.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
11934        }
11935
11936        // Handle special intents: if this broadcast is from the package
11937        // manager about a package being removed, we need to remove all of
11938        // its activities from the history stack.
11939        final boolean uidRemoved = intent.ACTION_UID_REMOVED.equals(
11940                intent.getAction());
11941        if (intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
11942                || intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
11943                || uidRemoved) {
11944            if (checkComponentPermission(
11945                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
11946                    callingPid, callingUid, -1)
11947                    == PackageManager.PERMISSION_GRANTED) {
11948                if (uidRemoved) {
11949                    final Bundle intentExtras = intent.getExtras();
11950                    final int uid = intentExtras != null
11951                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
11952                    if (uid >= 0) {
11953                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
11954                        synchronized (bs) {
11955                            bs.removeUidStatsLocked(uid);
11956                        }
11957                    }
11958                } else {
11959                    Uri data = intent.getData();
11960                    String ssp;
11961                    if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11962                        if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
11963                            forceStopPackageLocked(ssp,
11964                                    intent.getIntExtra(Intent.EXTRA_UID, -1), false);
11965                            AttributeCache ac = AttributeCache.instance();
11966                            if (ac != null) {
11967                                ac.removePackage(ssp);
11968                            }
11969                        }
11970                    }
11971                }
11972            } else {
11973                String msg = "Permission Denial: " + intent.getAction()
11974                        + " broadcast from " + callerPackage + " (pid=" + callingPid
11975                        + ", uid=" + callingUid + ")"
11976                        + " requires "
11977                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
11978                Log.w(TAG, msg);
11979                throw new SecurityException(msg);
11980            }
11981        }
11982
11983        /*
11984         * If this is the time zone changed action, queue up a message that will reset the timezone
11985         * of all currently running processes. This message will get queued up before the broadcast
11986         * happens.
11987         */
11988        if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
11989            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
11990        }
11991
11992        /*
11993         * Prevent non-system code (defined here to be non-persistent
11994         * processes) from sending protected broadcasts.
11995         */
11996        if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID
11997                || callingUid == Process.SHELL_UID || callingUid == 0) {
11998            // Always okay.
11999        } else if (callerApp == null || !callerApp.persistent) {
12000            try {
12001                if (ActivityThread.getPackageManager().isProtectedBroadcast(
12002                        intent.getAction())) {
12003                    String msg = "Permission Denial: not allowed to send broadcast "
12004                            + intent.getAction() + " from pid="
12005                            + callingPid + ", uid=" + callingUid;
12006                    Log.w(TAG, msg);
12007                    throw new SecurityException(msg);
12008                }
12009            } catch (RemoteException e) {
12010                Log.w(TAG, "Remote exception", e);
12011                return BROADCAST_SUCCESS;
12012            }
12013        }
12014
12015        // Add to the sticky list if requested.
12016        if (sticky) {
12017            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
12018                    callingPid, callingUid)
12019                    != PackageManager.PERMISSION_GRANTED) {
12020                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
12021                        + callingPid + ", uid=" + callingUid
12022                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
12023                Log.w(TAG, msg);
12024                throw new SecurityException(msg);
12025            }
12026            if (requiredPermission != null) {
12027                Log.w(TAG, "Can't broadcast sticky intent " + intent
12028                        + " and enforce permission " + requiredPermission);
12029                return BROADCAST_STICKY_CANT_HAVE_PERMISSION;
12030            }
12031            if (intent.getComponent() != null) {
12032                throw new SecurityException(
12033                        "Sticky broadcasts can't target a specific component");
12034            }
12035            ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
12036            if (list == null) {
12037                list = new ArrayList<Intent>();
12038                mStickyBroadcasts.put(intent.getAction(), list);
12039            }
12040            int N = list.size();
12041            int i;
12042            for (i=0; i<N; i++) {
12043                if (intent.filterEquals(list.get(i))) {
12044                    // This sticky already exists, replace it.
12045                    list.set(i, new Intent(intent));
12046                    break;
12047                }
12048            }
12049            if (i >= N) {
12050                list.add(new Intent(intent));
12051            }
12052        }
12053
12054        // Figure out who all will receive this broadcast.
12055        List receivers = null;
12056        List<BroadcastFilter> registeredReceivers = null;
12057        try {
12058            if (intent.getComponent() != null) {
12059                // Broadcast is going to one specific receiver class...
12060                ActivityInfo ai = ActivityThread.getPackageManager().
12061                    getReceiverInfo(intent.getComponent(), STOCK_PM_FLAGS);
12062                if (ai != null) {
12063                    receivers = new ArrayList();
12064                    ResolveInfo ri = new ResolveInfo();
12065                    ri.activityInfo = ai;
12066                    receivers.add(ri);
12067                }
12068            } else {
12069                // Need to resolve the intent to interested receivers...
12070                if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
12071                         == 0) {
12072                    receivers =
12073                        ActivityThread.getPackageManager().queryIntentReceivers(
12074                                intent, resolvedType, STOCK_PM_FLAGS);
12075                }
12076                registeredReceivers = mReceiverResolver.queryIntent(intent, resolvedType, false);
12077            }
12078        } catch (RemoteException ex) {
12079            // pm is in same process, this will never happen.
12080        }
12081
12082        final boolean replacePending =
12083                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
12084
12085        if (DEBUG_BROADCAST) Log.v(TAG, "Enqueing broadcast: " + intent.getAction()
12086                + " replacePending=" + replacePending);
12087
12088        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
12089        if (!ordered && NR > 0) {
12090            // If we are not serializing this broadcast, then send the
12091            // registered receivers separately so they don't wait for the
12092            // components to be launched.
12093            BroadcastRecord r = new BroadcastRecord(intent, callerApp,
12094                    callerPackage, callingPid, callingUid, requiredPermission,
12095                    registeredReceivers, resultTo, resultCode, resultData, map,
12096                    ordered, sticky, false);
12097            if (DEBUG_BROADCAST) Log.v(
12098                    TAG, "Enqueueing parallel broadcast " + r
12099                    + ": prev had " + mParallelBroadcasts.size());
12100            boolean replaced = false;
12101            if (replacePending) {
12102                for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
12103                    if (intent.filterEquals(mParallelBroadcasts.get(i).intent)) {
12104                        if (DEBUG_BROADCAST) Log.v(TAG,
12105                                "***** DROPPING PARALLEL: " + intent);
12106                        mParallelBroadcasts.set(i, r);
12107                        replaced = true;
12108                        break;
12109                    }
12110                }
12111            }
12112            if (!replaced) {
12113                mParallelBroadcasts.add(r);
12114                scheduleBroadcastsLocked();
12115            }
12116            registeredReceivers = null;
12117            NR = 0;
12118        }
12119
12120        // Merge into one list.
12121        int ir = 0;
12122        if (receivers != null) {
12123            // A special case for PACKAGE_ADDED: do not allow the package
12124            // being added to see this broadcast.  This prevents them from
12125            // using this as a back door to get run as soon as they are
12126            // installed.  Maybe in the future we want to have a special install
12127            // broadcast or such for apps, but we'd like to deliberately make
12128            // this decision.
12129            boolean skip = false;
12130            if (intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
12131                skip = true;
12132            } else if (intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())) {
12133                skip = true;
12134            } else if (intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
12135                skip = true;
12136            }
12137            String skipPackage = (skip && intent.getData() != null)
12138                    ? intent.getData().getSchemeSpecificPart()
12139                    : null;
12140            if (skipPackage != null && receivers != null) {
12141                int NT = receivers.size();
12142                for (int it=0; it<NT; it++) {
12143                    ResolveInfo curt = (ResolveInfo)receivers.get(it);
12144                    if (curt.activityInfo.packageName.equals(skipPackage)) {
12145                        receivers.remove(it);
12146                        it--;
12147                        NT--;
12148                    }
12149                }
12150            }
12151
12152            int NT = receivers != null ? receivers.size() : 0;
12153            int it = 0;
12154            ResolveInfo curt = null;
12155            BroadcastFilter curr = null;
12156            while (it < NT && ir < NR) {
12157                if (curt == null) {
12158                    curt = (ResolveInfo)receivers.get(it);
12159                }
12160                if (curr == null) {
12161                    curr = registeredReceivers.get(ir);
12162                }
12163                if (curr.getPriority() >= curt.priority) {
12164                    // Insert this broadcast record into the final list.
12165                    receivers.add(it, curr);
12166                    ir++;
12167                    curr = null;
12168                    it++;
12169                    NT++;
12170                } else {
12171                    // Skip to the next ResolveInfo in the final list.
12172                    it++;
12173                    curt = null;
12174                }
12175            }
12176        }
12177        while (ir < NR) {
12178            if (receivers == null) {
12179                receivers = new ArrayList();
12180            }
12181            receivers.add(registeredReceivers.get(ir));
12182            ir++;
12183        }
12184
12185        if ((receivers != null && receivers.size() > 0)
12186                || resultTo != null) {
12187            BroadcastRecord r = new BroadcastRecord(intent, callerApp,
12188                    callerPackage, callingPid, callingUid, requiredPermission,
12189                    receivers, resultTo, resultCode, resultData, map, ordered,
12190                    sticky, false);
12191            if (DEBUG_BROADCAST) Log.v(
12192                    TAG, "Enqueueing ordered broadcast " + r
12193                    + ": prev had " + mOrderedBroadcasts.size());
12194            if (DEBUG_BROADCAST) {
12195                int seq = r.intent.getIntExtra("seq", -1);
12196                Log.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
12197            }
12198            boolean replaced = false;
12199            if (replacePending) {
12200                for (int i=mOrderedBroadcasts.size()-1; i>=0; i--) {
12201                    if (intent.filterEquals(mOrderedBroadcasts.get(i).intent)) {
12202                        if (DEBUG_BROADCAST) Log.v(TAG,
12203                                "***** DROPPING ORDERED: " + intent);
12204                        mOrderedBroadcasts.set(i, r);
12205                        replaced = true;
12206                        break;
12207                    }
12208                }
12209            }
12210            if (!replaced) {
12211                mOrderedBroadcasts.add(r);
12212                scheduleBroadcastsLocked();
12213            }
12214        }
12215
12216        return BROADCAST_SUCCESS;
12217    }
12218
12219    public final int broadcastIntent(IApplicationThread caller,
12220            Intent intent, String resolvedType, IIntentReceiver resultTo,
12221            int resultCode, String resultData, Bundle map,
12222            String requiredPermission, boolean serialized, boolean sticky) {
12223        // Refuse possible leaked file descriptors
12224        if (intent != null && intent.hasFileDescriptors() == true) {
12225            throw new IllegalArgumentException("File descriptors passed in Intent");
12226        }
12227
12228        synchronized(this) {
12229            int flags = intent.getFlags();
12230
12231            if (!mSystemReady) {
12232                // if the caller really truly claims to know what they're doing, go
12233                // ahead and allow the broadcast without launching any receivers
12234                if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
12235                    intent = new Intent(intent);
12236                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
12237                } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0){
12238                    Log.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
12239                            + " before boot completion");
12240                    throw new IllegalStateException("Cannot broadcast before boot completed");
12241                }
12242            }
12243
12244            if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
12245                throw new IllegalArgumentException(
12246                        "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
12247            }
12248
12249            final ProcessRecord callerApp = getRecordForAppLocked(caller);
12250            final int callingPid = Binder.getCallingPid();
12251            final int callingUid = Binder.getCallingUid();
12252            final long origId = Binder.clearCallingIdentity();
12253            int res = broadcastIntentLocked(callerApp,
12254                    callerApp != null ? callerApp.info.packageName : null,
12255                    intent, resolvedType, resultTo,
12256                    resultCode, resultData, map, requiredPermission, serialized,
12257                    sticky, callingPid, callingUid);
12258            Binder.restoreCallingIdentity(origId);
12259            return res;
12260        }
12261    }
12262
12263    int broadcastIntentInPackage(String packageName, int uid,
12264            Intent intent, String resolvedType, IIntentReceiver resultTo,
12265            int resultCode, String resultData, Bundle map,
12266            String requiredPermission, boolean serialized, boolean sticky) {
12267        synchronized(this) {
12268            final long origId = Binder.clearCallingIdentity();
12269            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
12270                    resultTo, resultCode, resultData, map, requiredPermission,
12271                    serialized, sticky, -1, uid);
12272            Binder.restoreCallingIdentity(origId);
12273            return res;
12274        }
12275    }
12276
12277    public final void unbroadcastIntent(IApplicationThread caller,
12278            Intent intent) {
12279        // Refuse possible leaked file descriptors
12280        if (intent != null && intent.hasFileDescriptors() == true) {
12281            throw new IllegalArgumentException("File descriptors passed in Intent");
12282        }
12283
12284        synchronized(this) {
12285            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
12286                    != PackageManager.PERMISSION_GRANTED) {
12287                String msg = "Permission Denial: unbroadcastIntent() from pid="
12288                        + Binder.getCallingPid()
12289                        + ", uid=" + Binder.getCallingUid()
12290                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
12291                Log.w(TAG, msg);
12292                throw new SecurityException(msg);
12293            }
12294            ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
12295            if (list != null) {
12296                int N = list.size();
12297                int i;
12298                for (i=0; i<N; i++) {
12299                    if (intent.filterEquals(list.get(i))) {
12300                        list.remove(i);
12301                        break;
12302                    }
12303                }
12304            }
12305        }
12306    }
12307
12308    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
12309            String resultData, Bundle resultExtras, boolean resultAbort,
12310            boolean explicit) {
12311        if (mOrderedBroadcasts.size() == 0) {
12312            if (explicit) {
12313                Log.w(TAG, "finishReceiver called but no pending broadcasts");
12314            }
12315            return false;
12316        }
12317        BroadcastRecord r = mOrderedBroadcasts.get(0);
12318        if (r.receiver == null) {
12319            if (explicit) {
12320                Log.w(TAG, "finishReceiver called but none active");
12321            }
12322            return false;
12323        }
12324        if (r.receiver != receiver) {
12325            Log.w(TAG, "finishReceiver called but active receiver is different");
12326            return false;
12327        }
12328        int state = r.state;
12329        r.state = r.IDLE;
12330        if (state == r.IDLE) {
12331            if (explicit) {
12332                Log.w(TAG, "finishReceiver called but state is IDLE");
12333            }
12334        }
12335        r.receiver = null;
12336        r.intent.setComponent(null);
12337        if (r.curApp != null) {
12338            r.curApp.curReceiver = null;
12339        }
12340        if (r.curFilter != null) {
12341            r.curFilter.receiverList.curBroadcast = null;
12342        }
12343        r.curFilter = null;
12344        r.curApp = null;
12345        r.curComponent = null;
12346        r.curReceiver = null;
12347        mPendingBroadcast = null;
12348
12349        r.resultCode = resultCode;
12350        r.resultData = resultData;
12351        r.resultExtras = resultExtras;
12352        r.resultAbort = resultAbort;
12353
12354        // We will process the next receiver right now if this is finishing
12355        // an app receiver (which is always asynchronous) or after we have
12356        // come back from calling a receiver.
12357        return state == BroadcastRecord.APP_RECEIVE
12358                || state == BroadcastRecord.CALL_DONE_RECEIVE;
12359    }
12360
12361    public void finishReceiver(IBinder who, int resultCode, String resultData,
12362            Bundle resultExtras, boolean resultAbort) {
12363        if (DEBUG_BROADCAST) Log.v(TAG, "Finish receiver: " + who);
12364
12365        // Refuse possible leaked file descriptors
12366        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
12367            throw new IllegalArgumentException("File descriptors passed in Bundle");
12368        }
12369
12370        boolean doNext;
12371
12372        final long origId = Binder.clearCallingIdentity();
12373
12374        synchronized(this) {
12375            doNext = finishReceiverLocked(
12376                who, resultCode, resultData, resultExtras, resultAbort, true);
12377        }
12378
12379        if (doNext) {
12380            processNextBroadcast(false);
12381        }
12382        trimApplications();
12383
12384        Binder.restoreCallingIdentity(origId);
12385    }
12386
12387    private final void logBroadcastReceiverDiscard(BroadcastRecord r) {
12388        if (r.nextReceiver > 0) {
12389            Object curReceiver = r.receivers.get(r.nextReceiver-1);
12390            if (curReceiver instanceof BroadcastFilter) {
12391                BroadcastFilter bf = (BroadcastFilter) curReceiver;
12392                EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_FILTER,
12393                        System.identityHashCode(r),
12394                        r.intent.getAction(),
12395                        r.nextReceiver - 1,
12396                        System.identityHashCode(bf));
12397            } else {
12398                EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
12399                        System.identityHashCode(r),
12400                        r.intent.getAction(),
12401                        r.nextReceiver - 1,
12402                        ((ResolveInfo)curReceiver).toString());
12403            }
12404        } else {
12405            Log.w(TAG, "Discarding broadcast before first receiver is invoked: "
12406                    + r);
12407            EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
12408                    System.identityHashCode(r),
12409                    r.intent.getAction(),
12410                    r.nextReceiver,
12411                    "NONE");
12412        }
12413    }
12414
12415    private final void broadcastTimeout() {
12416        synchronized (this) {
12417            if (mOrderedBroadcasts.size() == 0) {
12418                return;
12419            }
12420            long now = SystemClock.uptimeMillis();
12421            BroadcastRecord r = mOrderedBroadcasts.get(0);
12422            if ((r.receiverTime+BROADCAST_TIMEOUT) > now) {
12423                if (DEBUG_BROADCAST) Log.v(TAG,
12424                        "Premature timeout @ " + now + ": resetting BROADCAST_TIMEOUT_MSG for "
12425                        + (r.receiverTime + BROADCAST_TIMEOUT));
12426                Message msg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG);
12427                mHandler.sendMessageAtTime(msg, r.receiverTime+BROADCAST_TIMEOUT);
12428                return;
12429            }
12430
12431            Log.w(TAG, "Timeout of broadcast " + r + " - receiver=" + r.receiver);
12432            r.receiverTime = now;
12433            r.anrCount++;
12434
12435            // Current receiver has passed its expiration date.
12436            if (r.nextReceiver <= 0) {
12437                Log.w(TAG, "Timeout on receiver with nextReceiver <= 0");
12438                return;
12439            }
12440
12441            ProcessRecord app = null;
12442
12443            Object curReceiver = r.receivers.get(r.nextReceiver-1);
12444            Log.w(TAG, "Receiver during timeout: " + curReceiver);
12445            logBroadcastReceiverDiscard(r);
12446            if (curReceiver instanceof BroadcastFilter) {
12447                BroadcastFilter bf = (BroadcastFilter)curReceiver;
12448                if (bf.receiverList.pid != 0
12449                        && bf.receiverList.pid != MY_PID) {
12450                    synchronized (this.mPidsSelfLocked) {
12451                        app = this.mPidsSelfLocked.get(
12452                                bf.receiverList.pid);
12453                    }
12454                }
12455            } else {
12456                app = r.curApp;
12457            }
12458
12459            if (app != null) {
12460                appNotRespondingLocked(app, null, null, "Broadcast of " + r.intent.toString());
12461            }
12462
12463            if (mPendingBroadcast == r) {
12464                mPendingBroadcast = null;
12465            }
12466
12467            // Move on to the next receiver.
12468            finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
12469                    r.resultExtras, r.resultAbort, true);
12470            scheduleBroadcastsLocked();
12471        }
12472    }
12473
12474    private final void processCurBroadcastLocked(BroadcastRecord r,
12475            ProcessRecord app) throws RemoteException {
12476        if (app.thread == null) {
12477            throw new RemoteException();
12478        }
12479        r.receiver = app.thread.asBinder();
12480        r.curApp = app;
12481        app.curReceiver = r;
12482        updateLruProcessLocked(app, true, true);
12483
12484        // Tell the application to launch this receiver.
12485        r.intent.setComponent(r.curComponent);
12486
12487        boolean started = false;
12488        try {
12489            if (DEBUG_BROADCAST_LIGHT) Log.v(TAG,
12490                    "Delivering to component " + r.curComponent
12491                    + ": " + r);
12492            ensurePackageDexOpt(r.intent.getComponent().getPackageName());
12493            app.thread.scheduleReceiver(new Intent(r.intent), r.curReceiver,
12494                    r.resultCode, r.resultData, r.resultExtras, r.ordered);
12495            started = true;
12496        } finally {
12497            if (!started) {
12498                r.receiver = null;
12499                r.curApp = null;
12500                app.curReceiver = null;
12501            }
12502        }
12503
12504    }
12505
12506    static void performReceive(ProcessRecord app, IIntentReceiver receiver,
12507            Intent intent, int resultCode, String data, Bundle extras,
12508            boolean ordered, boolean sticky) throws RemoteException {
12509        if (app != null && app.thread != null) {
12510            // If we have an app thread, do the call through that so it is
12511            // correctly ordered with other one-way calls.
12512            app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
12513                    data, extras, ordered, sticky);
12514        } else {
12515            receiver.performReceive(intent, resultCode, data, extras, ordered, sticky);
12516        }
12517    }
12518
12519    private final void deliverToRegisteredReceiver(BroadcastRecord r,
12520            BroadcastFilter filter, boolean ordered) {
12521        boolean skip = false;
12522        if (filter.requiredPermission != null) {
12523            int perm = checkComponentPermission(filter.requiredPermission,
12524                    r.callingPid, r.callingUid, -1);
12525            if (perm != PackageManager.PERMISSION_GRANTED) {
12526                Log.w(TAG, "Permission Denial: broadcasting "
12527                        + r.intent.toString()
12528                        + " from " + r.callerPackage + " (pid="
12529                        + r.callingPid + ", uid=" + r.callingUid + ")"
12530                        + " requires " + filter.requiredPermission
12531                        + " due to registered receiver " + filter);
12532                skip = true;
12533            }
12534        }
12535        if (r.requiredPermission != null) {
12536            int perm = checkComponentPermission(r.requiredPermission,
12537                    filter.receiverList.pid, filter.receiverList.uid, -1);
12538            if (perm != PackageManager.PERMISSION_GRANTED) {
12539                Log.w(TAG, "Permission Denial: receiving "
12540                        + r.intent.toString()
12541                        + " to " + filter.receiverList.app
12542                        + " (pid=" + filter.receiverList.pid
12543                        + ", uid=" + filter.receiverList.uid + ")"
12544                        + " requires " + r.requiredPermission
12545                        + " due to sender " + r.callerPackage
12546                        + " (uid " + r.callingUid + ")");
12547                skip = true;
12548            }
12549        }
12550
12551        if (!skip) {
12552            // If this is not being sent as an ordered broadcast, then we
12553            // don't want to touch the fields that keep track of the current
12554            // state of ordered broadcasts.
12555            if (ordered) {
12556                r.receiver = filter.receiverList.receiver.asBinder();
12557                r.curFilter = filter;
12558                filter.receiverList.curBroadcast = r;
12559                r.state = BroadcastRecord.CALL_IN_RECEIVE;
12560                if (filter.receiverList.app != null) {
12561                    // Bump hosting application to no longer be in background
12562                    // scheduling class.  Note that we can't do that if there
12563                    // isn't an app...  but we can only be in that case for
12564                    // things that directly call the IActivityManager API, which
12565                    // are already core system stuff so don't matter for this.
12566                    r.curApp = filter.receiverList.app;
12567                    filter.receiverList.app.curReceiver = r;
12568                    updateOomAdjLocked();
12569                }
12570            }
12571            try {
12572                if (DEBUG_BROADCAST_LIGHT) {
12573                    int seq = r.intent.getIntExtra("seq", -1);
12574                    Log.i(TAG, "Delivering to " + filter.receiverList.app
12575                            + " (seq=" + seq + "): " + r);
12576                }
12577                performReceive(filter.receiverList.app, filter.receiverList.receiver,
12578                    new Intent(r.intent), r.resultCode,
12579                    r.resultData, r.resultExtras, r.ordered, r.initialSticky);
12580                if (ordered) {
12581                    r.state = BroadcastRecord.CALL_DONE_RECEIVE;
12582                }
12583            } catch (RemoteException e) {
12584                Log.w(TAG, "Failure sending broadcast " + r.intent, e);
12585                if (ordered) {
12586                    r.receiver = null;
12587                    r.curFilter = null;
12588                    filter.receiverList.curBroadcast = null;
12589                    if (filter.receiverList.app != null) {
12590                        filter.receiverList.app.curReceiver = null;
12591                    }
12592                }
12593            }
12594        }
12595    }
12596
12597    private final void addBroadcastToHistoryLocked(BroadcastRecord r) {
12598        if (r.callingUid < 0) {
12599            // This was from a registerReceiver() call; ignore it.
12600            return;
12601        }
12602        System.arraycopy(mBroadcastHistory, 0, mBroadcastHistory, 1,
12603                MAX_BROADCAST_HISTORY-1);
12604        r.finishTime = SystemClock.uptimeMillis();
12605        mBroadcastHistory[0] = r;
12606    }
12607
12608    private final void processNextBroadcast(boolean fromMsg) {
12609        synchronized(this) {
12610            BroadcastRecord r;
12611
12612            if (DEBUG_BROADCAST) Log.v(TAG, "processNextBroadcast: "
12613                    + mParallelBroadcasts.size() + " broadcasts, "
12614                    + mOrderedBroadcasts.size() + " serialized broadcasts");
12615
12616            updateCpuStats();
12617
12618            if (fromMsg) {
12619                mBroadcastsScheduled = false;
12620            }
12621
12622            // First, deliver any non-serialized broadcasts right away.
12623            while (mParallelBroadcasts.size() > 0) {
12624                r = mParallelBroadcasts.remove(0);
12625                r.dispatchTime = SystemClock.uptimeMillis();
12626                final int N = r.receivers.size();
12627                if (DEBUG_BROADCAST_LIGHT) Log.v(TAG, "Processing parallel broadcast "
12628                        + r);
12629                for (int i=0; i<N; i++) {
12630                    Object target = r.receivers.get(i);
12631                    if (DEBUG_BROADCAST)  Log.v(TAG,
12632                            "Delivering non-serialized to registered "
12633                            + target + ": " + r);
12634                    deliverToRegisteredReceiver(r, (BroadcastFilter)target, false);
12635                }
12636                addBroadcastToHistoryLocked(r);
12637                if (DEBUG_BROADCAST_LIGHT) Log.v(TAG, "Done with parallel broadcast "
12638                        + r);
12639            }
12640
12641            // Now take care of the next serialized one...
12642
12643            // If we are waiting for a process to come up to handle the next
12644            // broadcast, then do nothing at this point.  Just in case, we
12645            // check that the process we're waiting for still exists.
12646            if (mPendingBroadcast != null) {
12647                if (DEBUG_BROADCAST_LIGHT) {
12648                    Log.v(TAG, "processNextBroadcast: waiting for "
12649                            + mPendingBroadcast.curApp);
12650                }
12651
12652                boolean isDead;
12653                synchronized (mPidsSelfLocked) {
12654                    isDead = (mPidsSelfLocked.get(mPendingBroadcast.curApp.pid) == null);
12655                }
12656                if (!isDead) {
12657                    // It's still alive, so keep waiting
12658                    return;
12659                } else {
12660                    Log.w(TAG, "pending app " + mPendingBroadcast.curApp
12661                            + " died before responding to broadcast");
12662                    mPendingBroadcast = null;
12663                }
12664            }
12665
12666            boolean looped = false;
12667
12668            do {
12669                if (mOrderedBroadcasts.size() == 0) {
12670                    // No more broadcasts pending, so all done!
12671                    scheduleAppGcsLocked();
12672                    if (looped) {
12673                        // If we had finished the last ordered broadcast, then
12674                        // make sure all processes have correct oom and sched
12675                        // adjustments.
12676                        updateOomAdjLocked();
12677                    }
12678                    return;
12679                }
12680                r = mOrderedBroadcasts.get(0);
12681                boolean forceReceive = false;
12682
12683                // Ensure that even if something goes awry with the timeout
12684                // detection, we catch "hung" broadcasts here, discard them,
12685                // and continue to make progress.
12686                int numReceivers = (r.receivers != null) ? r.receivers.size() : 0;
12687                long now = SystemClock.uptimeMillis();
12688                if (r.dispatchTime > 0) {
12689                    if ((numReceivers > 0) &&
12690                            (now > r.dispatchTime + (2*BROADCAST_TIMEOUT*numReceivers))) {
12691                        Log.w(TAG, "Hung broadcast discarded after timeout failure:"
12692                                + " now=" + now
12693                                + " dispatchTime=" + r.dispatchTime
12694                                + " startTime=" + r.receiverTime
12695                                + " intent=" + r.intent
12696                                + " numReceivers=" + numReceivers
12697                                + " nextReceiver=" + r.nextReceiver
12698                                + " state=" + r.state);
12699                        broadcastTimeout(); // forcibly finish this broadcast
12700                        forceReceive = true;
12701                        r.state = BroadcastRecord.IDLE;
12702                    }
12703                }
12704
12705                if (r.state != BroadcastRecord.IDLE) {
12706                    if (DEBUG_BROADCAST) Log.d(TAG,
12707                            "processNextBroadcast() called when not idle (state="
12708                            + r.state + ")");
12709                    return;
12710                }
12711
12712                if (r.receivers == null || r.nextReceiver >= numReceivers
12713                        || r.resultAbort || forceReceive) {
12714                    // No more receivers for this broadcast!  Send the final
12715                    // result if requested...
12716                    if (r.resultTo != null) {
12717                        try {
12718                            if (DEBUG_BROADCAST) {
12719                                int seq = r.intent.getIntExtra("seq", -1);
12720                                Log.i(TAG, "Finishing broadcast " + r.intent.getAction()
12721                                        + " seq=" + seq + " app=" + r.callerApp);
12722                            }
12723                            performReceive(r.callerApp, r.resultTo,
12724                                new Intent(r.intent), r.resultCode,
12725                                r.resultData, r.resultExtras, false, false);
12726                        } catch (RemoteException e) {
12727                            Log.w(TAG, "Failure sending broadcast result of " + r.intent, e);
12728                        }
12729                    }
12730
12731                    if (DEBUG_BROADCAST) Log.v(TAG, "Cancelling BROADCAST_TIMEOUT_MSG");
12732                    mHandler.removeMessages(BROADCAST_TIMEOUT_MSG);
12733
12734                    if (DEBUG_BROADCAST_LIGHT) Log.v(TAG, "Finished with ordered broadcast "
12735                            + r);
12736
12737                    // ... and on to the next...
12738                    addBroadcastToHistoryLocked(r);
12739                    mOrderedBroadcasts.remove(0);
12740                    r = null;
12741                    looped = true;
12742                    continue;
12743                }
12744            } while (r == null);
12745
12746            // Get the next receiver...
12747            int recIdx = r.nextReceiver++;
12748
12749            // Keep track of when this receiver started, and make sure there
12750            // is a timeout message pending to kill it if need be.
12751            r.receiverTime = SystemClock.uptimeMillis();
12752            if (recIdx == 0) {
12753                r.dispatchTime = r.receiverTime;
12754
12755                if (DEBUG_BROADCAST_LIGHT) Log.v(TAG, "Processing ordered broadcast "
12756                        + r);
12757                if (DEBUG_BROADCAST) Log.v(TAG,
12758                        "Submitting BROADCAST_TIMEOUT_MSG for "
12759                        + (r.receiverTime + BROADCAST_TIMEOUT));
12760                Message msg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG);
12761                mHandler.sendMessageAtTime(msg, r.receiverTime+BROADCAST_TIMEOUT);
12762            }
12763
12764            Object nextReceiver = r.receivers.get(recIdx);
12765            if (nextReceiver instanceof BroadcastFilter) {
12766                // Simple case: this is a registered receiver who gets
12767                // a direct call.
12768                BroadcastFilter filter = (BroadcastFilter)nextReceiver;
12769                if (DEBUG_BROADCAST)  Log.v(TAG,
12770                        "Delivering serialized to registered "
12771                        + filter + ": " + r);
12772                deliverToRegisteredReceiver(r, filter, r.ordered);
12773                if (r.receiver == null || !r.ordered) {
12774                    // The receiver has already finished, so schedule to
12775                    // process the next one.
12776                    r.state = BroadcastRecord.IDLE;
12777                    scheduleBroadcastsLocked();
12778                }
12779                return;
12780            }
12781
12782            // Hard case: need to instantiate the receiver, possibly
12783            // starting its application process to host it.
12784
12785            ResolveInfo info =
12786                (ResolveInfo)nextReceiver;
12787
12788            boolean skip = false;
12789            int perm = checkComponentPermission(info.activityInfo.permission,
12790                    r.callingPid, r.callingUid,
12791                    info.activityInfo.exported
12792                            ? -1 : info.activityInfo.applicationInfo.uid);
12793            if (perm != PackageManager.PERMISSION_GRANTED) {
12794                Log.w(TAG, "Permission Denial: broadcasting "
12795                        + r.intent.toString()
12796                        + " from " + r.callerPackage + " (pid=" + r.callingPid
12797                        + ", uid=" + r.callingUid + ")"
12798                        + " requires " + info.activityInfo.permission
12799                        + " due to receiver " + info.activityInfo.packageName
12800                        + "/" + info.activityInfo.name);
12801                skip = true;
12802            }
12803            if (r.callingUid != Process.SYSTEM_UID &&
12804                r.requiredPermission != null) {
12805                try {
12806                    perm = ActivityThread.getPackageManager().
12807                            checkPermission(r.requiredPermission,
12808                                    info.activityInfo.applicationInfo.packageName);
12809                } catch (RemoteException e) {
12810                    perm = PackageManager.PERMISSION_DENIED;
12811                }
12812                if (perm != PackageManager.PERMISSION_GRANTED) {
12813                    Log.w(TAG, "Permission Denial: receiving "
12814                            + r.intent + " to "
12815                            + info.activityInfo.applicationInfo.packageName
12816                            + " requires " + r.requiredPermission
12817                            + " due to sender " + r.callerPackage
12818                            + " (uid " + r.callingUid + ")");
12819                    skip = true;
12820                }
12821            }
12822            if (r.curApp != null && r.curApp.crashing) {
12823                // If the target process is crashing, just skip it.
12824                skip = true;
12825            }
12826
12827            if (skip) {
12828                r.receiver = null;
12829                r.curFilter = null;
12830                r.state = BroadcastRecord.IDLE;
12831                scheduleBroadcastsLocked();
12832                return;
12833            }
12834
12835            r.state = BroadcastRecord.APP_RECEIVE;
12836            String targetProcess = info.activityInfo.processName;
12837            r.curComponent = new ComponentName(
12838                    info.activityInfo.applicationInfo.packageName,
12839                    info.activityInfo.name);
12840            r.curReceiver = info.activityInfo;
12841
12842            // Is this receiver's application already running?
12843            ProcessRecord app = getProcessRecordLocked(targetProcess,
12844                    info.activityInfo.applicationInfo.uid);
12845            if (app != null && app.thread != null) {
12846                try {
12847                    processCurBroadcastLocked(r, app);
12848                    return;
12849                } catch (RemoteException e) {
12850                    Log.w(TAG, "Exception when sending broadcast to "
12851                          + r.curComponent, e);
12852                }
12853
12854                // If a dead object exception was thrown -- fall through to
12855                // restart the application.
12856            }
12857
12858            // Not running -- get it started, to be executed when the app comes up.
12859            if ((r.curApp=startProcessLocked(targetProcess,
12860                    info.activityInfo.applicationInfo, true,
12861                    r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND,
12862                    "broadcast", r.curComponent,
12863                    (r.intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0))
12864                            == null) {
12865                // Ah, this recipient is unavailable.  Finish it if necessary,
12866                // and mark the broadcast record as ready for the next.
12867                Log.w(TAG, "Unable to launch app "
12868                        + info.activityInfo.applicationInfo.packageName + "/"
12869                        + info.activityInfo.applicationInfo.uid + " for broadcast "
12870                        + r.intent + ": process is bad");
12871                logBroadcastReceiverDiscard(r);
12872                finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
12873                        r.resultExtras, r.resultAbort, true);
12874                scheduleBroadcastsLocked();
12875                r.state = BroadcastRecord.IDLE;
12876                return;
12877            }
12878
12879            mPendingBroadcast = r;
12880        }
12881    }
12882
12883    // =========================================================
12884    // INSTRUMENTATION
12885    // =========================================================
12886
12887    public boolean startInstrumentation(ComponentName className,
12888            String profileFile, int flags, Bundle arguments,
12889            IInstrumentationWatcher watcher) {
12890        // Refuse possible leaked file descriptors
12891        if (arguments != null && arguments.hasFileDescriptors()) {
12892            throw new IllegalArgumentException("File descriptors passed in Bundle");
12893        }
12894
12895        synchronized(this) {
12896            InstrumentationInfo ii = null;
12897            ApplicationInfo ai = null;
12898            try {
12899                ii = mContext.getPackageManager().getInstrumentationInfo(
12900                    className, STOCK_PM_FLAGS);
12901                ai = mContext.getPackageManager().getApplicationInfo(
12902                    ii.targetPackage, STOCK_PM_FLAGS);
12903            } catch (PackageManager.NameNotFoundException e) {
12904            }
12905            if (ii == null) {
12906                reportStartInstrumentationFailure(watcher, className,
12907                        "Unable to find instrumentation info for: " + className);
12908                return false;
12909            }
12910            if (ai == null) {
12911                reportStartInstrumentationFailure(watcher, className,
12912                        "Unable to find instrumentation target package: " + ii.targetPackage);
12913                return false;
12914            }
12915
12916            int match = mContext.getPackageManager().checkSignatures(
12917                    ii.targetPackage, ii.packageName);
12918            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
12919                String msg = "Permission Denial: starting instrumentation "
12920                        + className + " from pid="
12921                        + Binder.getCallingPid()
12922                        + ", uid=" + Binder.getCallingPid()
12923                        + " not allowed because package " + ii.packageName
12924                        + " does not have a signature matching the target "
12925                        + ii.targetPackage;
12926                reportStartInstrumentationFailure(watcher, className, msg);
12927                throw new SecurityException(msg);
12928            }
12929
12930            final long origId = Binder.clearCallingIdentity();
12931            forceStopPackageLocked(ii.targetPackage, -1, true);
12932            ProcessRecord app = addAppLocked(ai);
12933            app.instrumentationClass = className;
12934            app.instrumentationInfo = ai;
12935            app.instrumentationProfileFile = profileFile;
12936            app.instrumentationArguments = arguments;
12937            app.instrumentationWatcher = watcher;
12938            app.instrumentationResultClass = className;
12939            Binder.restoreCallingIdentity(origId);
12940        }
12941
12942        return true;
12943    }
12944
12945    /**
12946     * Report errors that occur while attempting to start Instrumentation.  Always writes the
12947     * error to the logs, but if somebody is watching, send the report there too.  This enables
12948     * the "am" command to report errors with more information.
12949     *
12950     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
12951     * @param cn The component name of the instrumentation.
12952     * @param report The error report.
12953     */
12954    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
12955            ComponentName cn, String report) {
12956        Log.w(TAG, report);
12957        try {
12958            if (watcher != null) {
12959                Bundle results = new Bundle();
12960                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
12961                results.putString("Error", report);
12962                watcher.instrumentationStatus(cn, -1, results);
12963            }
12964        } catch (RemoteException e) {
12965            Log.w(TAG, e);
12966        }
12967    }
12968
12969    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
12970        if (app.instrumentationWatcher != null) {
12971            try {
12972                // NOTE:  IInstrumentationWatcher *must* be oneway here
12973                app.instrumentationWatcher.instrumentationFinished(
12974                    app.instrumentationClass,
12975                    resultCode,
12976                    results);
12977            } catch (RemoteException e) {
12978            }
12979        }
12980        app.instrumentationWatcher = null;
12981        app.instrumentationClass = null;
12982        app.instrumentationInfo = null;
12983        app.instrumentationProfileFile = null;
12984        app.instrumentationArguments = null;
12985
12986        forceStopPackageLocked(app.processName, -1, false);
12987    }
12988
12989    public void finishInstrumentation(IApplicationThread target,
12990            int resultCode, Bundle results) {
12991        // Refuse possible leaked file descriptors
12992        if (results != null && results.hasFileDescriptors()) {
12993            throw new IllegalArgumentException("File descriptors passed in Intent");
12994        }
12995
12996        synchronized(this) {
12997            ProcessRecord app = getRecordForAppLocked(target);
12998            if (app == null) {
12999                Log.w(TAG, "finishInstrumentation: no app for " + target);
13000                return;
13001            }
13002            final long origId = Binder.clearCallingIdentity();
13003            finishInstrumentationLocked(app, resultCode, results);
13004            Binder.restoreCallingIdentity(origId);
13005        }
13006    }
13007
13008    // =========================================================
13009    // CONFIGURATION
13010    // =========================================================
13011
13012    public ConfigurationInfo getDeviceConfigurationInfo() {
13013        ConfigurationInfo config = new ConfigurationInfo();
13014        synchronized (this) {
13015            config.reqTouchScreen = mConfiguration.touchscreen;
13016            config.reqKeyboardType = mConfiguration.keyboard;
13017            config.reqNavigation = mConfiguration.navigation;
13018            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
13019                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
13020                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
13021            }
13022            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
13023                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
13024                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
13025            }
13026            config.reqGlEsVersion = GL_ES_VERSION;
13027        }
13028        return config;
13029    }
13030
13031    public Configuration getConfiguration() {
13032        Configuration ci;
13033        synchronized(this) {
13034            ci = new Configuration(mConfiguration);
13035        }
13036        return ci;
13037    }
13038
13039    public void updateConfiguration(Configuration values) {
13040        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
13041                "updateConfiguration()");
13042
13043        synchronized(this) {
13044            if (values == null && mWindowManager != null) {
13045                // sentinel: fetch the current configuration from the window manager
13046                values = mWindowManager.computeNewConfiguration();
13047            }
13048
13049            final long origId = Binder.clearCallingIdentity();
13050            updateConfigurationLocked(values, null);
13051            Binder.restoreCallingIdentity(origId);
13052        }
13053    }
13054
13055    /**
13056     * Do either or both things: (1) change the current configuration, and (2)
13057     * make sure the given activity is running with the (now) current
13058     * configuration.  Returns true if the activity has been left running, or
13059     * false if <var>starting</var> is being destroyed to match the new
13060     * configuration.
13061     */
13062    public boolean updateConfigurationLocked(Configuration values,
13063            HistoryRecord starting) {
13064        int changes = 0;
13065
13066        boolean kept = true;
13067
13068        if (values != null) {
13069            Configuration newConfig = new Configuration(mConfiguration);
13070            changes = newConfig.updateFrom(values);
13071            if (changes != 0) {
13072                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
13073                    Log.i(TAG, "Updating configuration to: " + values);
13074                }
13075
13076                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
13077
13078                if (values.locale != null) {
13079                    saveLocaleLocked(values.locale,
13080                                     !values.locale.equals(mConfiguration.locale),
13081                                     values.userSetLocale);
13082                }
13083
13084                mConfiguration = newConfig;
13085                Log.i(TAG, "Config changed: " + newConfig);
13086
13087                AttributeCache ac = AttributeCache.instance();
13088                if (ac != null) {
13089                    ac.updateConfiguration(mConfiguration);
13090                }
13091
13092                Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
13093                msg.obj = new Configuration(mConfiguration);
13094                mHandler.sendMessage(msg);
13095
13096                for (int i=mLruProcesses.size()-1; i>=0; i--) {
13097                    ProcessRecord app = mLruProcesses.get(i);
13098                    try {
13099                        if (app.thread != null) {
13100                            if (DEBUG_CONFIGURATION) Log.v(TAG, "Sending to proc "
13101                                    + app.processName + " new config " + mConfiguration);
13102                            app.thread.scheduleConfigurationChanged(mConfiguration);
13103                        }
13104                    } catch (Exception e) {
13105                    }
13106                }
13107                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
13108                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
13109                        | Intent.FLAG_RECEIVER_REPLACE_PENDING);
13110                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
13111                        null, false, false, MY_PID, Process.SYSTEM_UID);
13112                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
13113                    broadcastIntentLocked(null, null,
13114                            new Intent(Intent.ACTION_LOCALE_CHANGED),
13115                            null, null, 0, null, null,
13116                            null, false, false, MY_PID, Process.SYSTEM_UID);
13117                }
13118            }
13119        }
13120
13121        if (changes != 0 && starting == null) {
13122            // If the configuration changed, and the caller is not already
13123            // in the process of starting an activity, then find the top
13124            // activity to check if its configuration needs to change.
13125            starting = topRunningActivityLocked(null);
13126        }
13127
13128        if (starting != null) {
13129            kept = ensureActivityConfigurationLocked(starting, changes);
13130            if (kept) {
13131                // If this didn't result in the starting activity being
13132                // destroyed, then we need to make sure at this point that all
13133                // other activities are made visible.
13134                if (DEBUG_SWITCH) Log.i(TAG, "Config didn't destroy " + starting
13135                        + ", ensuring others are correct.");
13136                ensureActivitiesVisibleLocked(starting, changes);
13137            }
13138        }
13139
13140        return kept;
13141    }
13142
13143    private final boolean relaunchActivityLocked(HistoryRecord r,
13144            int changes, boolean andResume) {
13145        List<ResultInfo> results = null;
13146        List<Intent> newIntents = null;
13147        if (andResume) {
13148            results = r.results;
13149            newIntents = r.newIntents;
13150        }
13151        if (DEBUG_SWITCH) Log.v(TAG, "Relaunching: " + r
13152                + " with results=" + results + " newIntents=" + newIntents
13153                + " andResume=" + andResume);
13154        EventLog.writeEvent(andResume ? EventLogTags.AM_RELAUNCH_RESUME_ACTIVITY
13155                : EventLogTags.AM_RELAUNCH_ACTIVITY, System.identityHashCode(r),
13156                r.task.taskId, r.shortComponentName);
13157
13158        r.startFreezingScreenLocked(r.app, 0);
13159
13160        try {
13161            if (DEBUG_SWITCH) Log.i(TAG, "Switch is restarting resumed " + r);
13162            r.app.thread.scheduleRelaunchActivity(r, results, newIntents,
13163                    changes, !andResume, mConfiguration);
13164            // Note: don't need to call pauseIfSleepingLocked() here, because
13165            // the caller will only pass in 'andResume' if this activity is
13166            // currently resumed, which implies we aren't sleeping.
13167        } catch (RemoteException e) {
13168            return false;
13169        }
13170
13171        if (andResume) {
13172            r.results = null;
13173            r.newIntents = null;
13174            reportResumedActivityLocked(r);
13175        }
13176
13177        return true;
13178    }
13179
13180    /**
13181     * Make sure the given activity matches the current configuration.  Returns
13182     * false if the activity had to be destroyed.  Returns true if the
13183     * configuration is the same, or the activity will remain running as-is
13184     * for whatever reason.  Ensures the HistoryRecord is updated with the
13185     * correct configuration and all other bookkeeping is handled.
13186     */
13187    private final boolean ensureActivityConfigurationLocked(HistoryRecord r,
13188            int globalChanges) {
13189        if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Log.v(TAG,
13190                "Ensuring correct configuration: " + r);
13191
13192        // Short circuit: if the two configurations are the exact same
13193        // object (the common case), then there is nothing to do.
13194        Configuration newConfig = mConfiguration;
13195        if (r.configuration == newConfig) {
13196            if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Log.v(TAG,
13197                    "Configuration unchanged in " + r);
13198            return true;
13199        }
13200
13201        // We don't worry about activities that are finishing.
13202        if (r.finishing) {
13203            if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Log.v(TAG,
13204                    "Configuration doesn't matter in finishing " + r);
13205            r.stopFreezingScreenLocked(false);
13206            return true;
13207        }
13208
13209        // Okay we now are going to make this activity have the new config.
13210        // But then we need to figure out how it needs to deal with that.
13211        Configuration oldConfig = r.configuration;
13212        r.configuration = newConfig;
13213
13214        // If the activity isn't currently running, just leave the new
13215        // configuration and it will pick that up next time it starts.
13216        if (r.app == null || r.app.thread == null) {
13217            if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Log.v(TAG,
13218                    "Configuration doesn't matter not running " + r);
13219            r.stopFreezingScreenLocked(false);
13220            return true;
13221        }
13222
13223        // If the activity isn't persistent, there is a chance we will
13224        // need to restart it.
13225        if (!r.persistent) {
13226
13227            // Figure out what has changed between the two configurations.
13228            int changes = oldConfig.diff(newConfig);
13229            if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
13230                Log.v(TAG, "Checking to restart " + r.info.name + ": changed=0x"
13231                        + Integer.toHexString(changes) + ", handles=0x"
13232                        + Integer.toHexString(r.info.configChanges)
13233                        + ", newConfig=" + newConfig);
13234            }
13235            if ((changes&(~r.info.configChanges)) != 0) {
13236                // Aha, the activity isn't handling the change, so DIE DIE DIE.
13237                r.configChangeFlags |= changes;
13238                r.startFreezingScreenLocked(r.app, globalChanges);
13239                if (r.app == null || r.app.thread == null) {
13240                    if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Log.v(TAG,
13241                            "Switch is destroying non-running " + r);
13242                    destroyActivityLocked(r, true);
13243                } else if (r.state == ActivityState.PAUSING) {
13244                    // A little annoying: we are waiting for this activity to
13245                    // finish pausing.  Let's not do anything now, but just
13246                    // flag that it needs to be restarted when done pausing.
13247                    if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Log.v(TAG,
13248                            "Switch is skipping already pausing " + r);
13249                    r.configDestroy = true;
13250                    return true;
13251                } else if (r.state == ActivityState.RESUMED) {
13252                    // Try to optimize this case: the configuration is changing
13253                    // and we need to restart the top, resumed activity.
13254                    // Instead of doing the normal handshaking, just say
13255                    // "restart!".
13256                    if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Log.v(TAG,
13257                            "Switch is restarting resumed " + r);
13258                    relaunchActivityLocked(r, r.configChangeFlags, true);
13259                    r.configChangeFlags = 0;
13260                } else {
13261                    if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Log.v(TAG,
13262                            "Switch is restarting non-resumed " + r);
13263                    relaunchActivityLocked(r, r.configChangeFlags, false);
13264                    r.configChangeFlags = 0;
13265                }
13266
13267                // All done...  tell the caller we weren't able to keep this
13268                // activity around.
13269                return false;
13270            }
13271        }
13272
13273        // Default case: the activity can handle this new configuration, so
13274        // hand it over.  Note that we don't need to give it the new
13275        // configuration, since we always send configuration changes to all
13276        // process when they happen so it can just use whatever configuration
13277        // it last got.
13278        if (r.app != null && r.app.thread != null) {
13279            try {
13280                if (DEBUG_CONFIGURATION) Log.v(TAG, "Sending new config to " + r);
13281                r.app.thread.scheduleActivityConfigurationChanged(r);
13282            } catch (RemoteException e) {
13283                // If process died, whatever.
13284            }
13285        }
13286        r.stopFreezingScreenLocked(false);
13287
13288        return true;
13289    }
13290
13291    /**
13292     * Save the locale.  You must be inside a synchronized (this) block.
13293     */
13294    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
13295        if(isDiff) {
13296            SystemProperties.set("user.language", l.getLanguage());
13297            SystemProperties.set("user.region", l.getCountry());
13298        }
13299
13300        if(isPersist) {
13301            SystemProperties.set("persist.sys.language", l.getLanguage());
13302            SystemProperties.set("persist.sys.country", l.getCountry());
13303            SystemProperties.set("persist.sys.localevar", l.getVariant());
13304        }
13305    }
13306
13307    // =========================================================
13308    // LIFETIME MANAGEMENT
13309    // =========================================================
13310
13311    private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj,
13312            ProcessRecord TOP_APP, boolean recursed) {
13313        if (mAdjSeq == app.adjSeq) {
13314            // This adjustment has already been computed.  If we are calling
13315            // from the top, we may have already computed our adjustment with
13316            // an earlier hidden adjustment that isn't really for us... if
13317            // so, use the new hidden adjustment.
13318            if (!recursed && app.hidden) {
13319                app.curAdj = hiddenAdj;
13320            }
13321            return app.curAdj;
13322        }
13323
13324        if (app.thread == null) {
13325            app.adjSeq = mAdjSeq;
13326            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
13327            return (app.curAdj=EMPTY_APP_ADJ);
13328        }
13329
13330        if (app.maxAdj <= FOREGROUND_APP_ADJ) {
13331            // The max adjustment doesn't allow this app to be anything
13332            // below foreground, so it is not worth doing work for it.
13333            app.adjType = "fixed";
13334            app.adjSeq = mAdjSeq;
13335            app.curRawAdj = app.maxAdj;
13336            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
13337            return (app.curAdj=app.maxAdj);
13338       }
13339
13340        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
13341        app.adjSource = null;
13342        app.adjTarget = null;
13343        app.empty = false;
13344        app.hidden = false;
13345
13346        // Determine the importance of the process, starting with most
13347        // important to least, and assign an appropriate OOM adjustment.
13348        int adj;
13349        int schedGroup;
13350        int N;
13351        if (app == TOP_APP) {
13352            // The last app on the list is the foreground app.
13353            adj = FOREGROUND_APP_ADJ;
13354            schedGroup = Process.THREAD_GROUP_DEFAULT;
13355            app.adjType = "top-activity";
13356        } else if (app.instrumentationClass != null) {
13357            // Don't want to kill running instrumentation.
13358            adj = FOREGROUND_APP_ADJ;
13359            schedGroup = Process.THREAD_GROUP_DEFAULT;
13360            app.adjType = "instrumentation";
13361        } else if (app.persistentActivities > 0) {
13362            // Special persistent activities...  shouldn't be used these days.
13363            adj = FOREGROUND_APP_ADJ;
13364            schedGroup = Process.THREAD_GROUP_DEFAULT;
13365            app.adjType = "persistent";
13366        } else if (app.curReceiver != null ||
13367                (mPendingBroadcast != null && mPendingBroadcast.curApp == app)) {
13368            // An app that is currently receiving a broadcast also
13369            // counts as being in the foreground.
13370            adj = FOREGROUND_APP_ADJ;
13371            schedGroup = Process.THREAD_GROUP_DEFAULT;
13372            app.adjType = "broadcast";
13373        } else if (app.executingServices.size() > 0) {
13374            // An app that is currently executing a service callback also
13375            // counts as being in the foreground.
13376            adj = FOREGROUND_APP_ADJ;
13377            schedGroup = Process.THREAD_GROUP_DEFAULT;
13378            app.adjType = "exec-service";
13379        } else if (app.foregroundServices) {
13380            // The user is aware of this app, so make it visible.
13381            adj = VISIBLE_APP_ADJ;
13382            schedGroup = Process.THREAD_GROUP_DEFAULT;
13383            app.adjType = "foreground-service";
13384        } else if (app.forcingToForeground != null) {
13385            // The user is aware of this app, so make it visible.
13386            adj = VISIBLE_APP_ADJ;
13387            schedGroup = Process.THREAD_GROUP_DEFAULT;
13388            app.adjType = "force-foreground";
13389            app.adjSource = app.forcingToForeground;
13390        } else if (app == mHomeProcess) {
13391            // This process is hosting what we currently consider to be the
13392            // home app, so we don't want to let it go into the background.
13393            adj = HOME_APP_ADJ;
13394            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
13395            app.adjType = "home";
13396        } else if ((N=app.activities.size()) != 0) {
13397            // This app is in the background with paused activities.
13398            app.hidden = true;
13399            adj = hiddenAdj;
13400            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
13401            app.adjType = "bg-activities";
13402            N = app.activities.size();
13403            for (int j=0; j<N; j++) {
13404                if (((HistoryRecord)app.activities.get(j)).visible) {
13405                    // This app has a visible activity!
13406                    app.hidden = false;
13407                    adj = VISIBLE_APP_ADJ;
13408                    schedGroup = Process.THREAD_GROUP_DEFAULT;
13409                    app.adjType = "visible";
13410                    break;
13411                }
13412            }
13413        } else {
13414            // A very not-needed process.  If this is lower in the lru list,
13415            // we will push it in to the empty bucket.
13416            app.hidden = true;
13417            app.empty = true;
13418            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
13419            adj = hiddenAdj;
13420            app.adjType = "bg-empty";
13421        }
13422
13423        //Log.i(TAG, "OOM " + app + ": initial adj=" + adj);
13424
13425        // By default, we use the computed adjustment.  It may be changed if
13426        // there are applications dependent on our services or providers, but
13427        // this gives us a baseline and makes sure we don't get into an
13428        // infinite recursion.
13429        app.adjSeq = mAdjSeq;
13430        app.curRawAdj = adj;
13431
13432        if (mBackupTarget != null && app == mBackupTarget.app) {
13433            // If possible we want to avoid killing apps while they're being backed up
13434            if (adj > BACKUP_APP_ADJ) {
13435                if (DEBUG_BACKUP) Log.v(TAG, "oom BACKUP_APP_ADJ for " + app);
13436                adj = BACKUP_APP_ADJ;
13437                app.adjType = "backup";
13438                app.hidden = false;
13439            }
13440        }
13441
13442        if (app.services.size() != 0 && (adj > FOREGROUND_APP_ADJ
13443                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
13444            final long now = SystemClock.uptimeMillis();
13445            // This process is more important if the top activity is
13446            // bound to the service.
13447            Iterator jt = app.services.iterator();
13448            while (jt.hasNext() && adj > FOREGROUND_APP_ADJ) {
13449                ServiceRecord s = (ServiceRecord)jt.next();
13450                if (s.startRequested) {
13451                    if (now < (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
13452                        // This service has seen some activity within
13453                        // recent memory, so we will keep its process ahead
13454                        // of the background processes.
13455                        if (adj > SECONDARY_SERVER_ADJ) {
13456                            adj = SECONDARY_SERVER_ADJ;
13457                            app.adjType = "started-services";
13458                            app.hidden = false;
13459                        }
13460                    }
13461                }
13462                if (s.connections.size() > 0 && (adj > FOREGROUND_APP_ADJ
13463                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
13464                    Iterator<ConnectionRecord> kt
13465                            = s.connections.values().iterator();
13466                    while (kt.hasNext() && adj > FOREGROUND_APP_ADJ) {
13467                        // XXX should compute this based on the max of
13468                        // all connected clients.
13469                        ConnectionRecord cr = kt.next();
13470                        if (cr.binding.client == app) {
13471                            // Binding to ourself is not interesting.
13472                            continue;
13473                        }
13474                        if ((cr.flags&Context.BIND_AUTO_CREATE) != 0) {
13475                            ProcessRecord client = cr.binding.client;
13476                            int myHiddenAdj = hiddenAdj;
13477                            if (myHiddenAdj > client.hiddenAdj) {
13478                                if (client.hiddenAdj > VISIBLE_APP_ADJ) {
13479                                    myHiddenAdj = client.hiddenAdj;
13480                                } else {
13481                                    myHiddenAdj = VISIBLE_APP_ADJ;
13482                                }
13483                            }
13484                            int clientAdj = computeOomAdjLocked(
13485                                client, myHiddenAdj, TOP_APP, true);
13486                            if (adj > clientAdj) {
13487                                adj = clientAdj > VISIBLE_APP_ADJ
13488                                        ? clientAdj : VISIBLE_APP_ADJ;
13489                                if (!client.hidden) {
13490                                    app.hidden = false;
13491                                }
13492                                app.adjType = "service";
13493                                app.adjTypeCode = ActivityManager.RunningAppProcessInfo
13494                                        .REASON_SERVICE_IN_USE;
13495                                app.adjSource = cr.binding.client;
13496                                app.adjTarget = s.serviceInfo.name;
13497                            }
13498                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
13499                                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
13500                                    schedGroup = Process.THREAD_GROUP_DEFAULT;
13501                                }
13502                            }
13503                        }
13504                        HistoryRecord a = cr.activity;
13505                        //if (a != null) {
13506                        //    Log.i(TAG, "Connection to " + a ": state=" + a.state);
13507                        //}
13508                        if (a != null && adj > FOREGROUND_APP_ADJ &&
13509                                (a.state == ActivityState.RESUMED
13510                                 || a.state == ActivityState.PAUSING)) {
13511                            adj = FOREGROUND_APP_ADJ;
13512                            schedGroup = Process.THREAD_GROUP_DEFAULT;
13513                            app.hidden = false;
13514                            app.adjType = "service";
13515                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
13516                                    .REASON_SERVICE_IN_USE;
13517                            app.adjSource = a;
13518                            app.adjTarget = s.serviceInfo.name;
13519                        }
13520                    }
13521                }
13522            }
13523
13524            // Finally, f this process has active services running in it, we
13525            // would like to avoid killing it unless it would prevent the current
13526            // application from running.  By default we put the process in
13527            // with the rest of the background processes; as we scan through
13528            // its services we may bump it up from there.
13529            if (adj > hiddenAdj) {
13530                adj = hiddenAdj;
13531                app.hidden = false;
13532                app.adjType = "bg-services";
13533            }
13534        }
13535
13536        if (app.pubProviders.size() != 0 && (adj > FOREGROUND_APP_ADJ
13537                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
13538            Iterator jt = app.pubProviders.values().iterator();
13539            while (jt.hasNext() && (adj > FOREGROUND_APP_ADJ
13540                    || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
13541                ContentProviderRecord cpr = (ContentProviderRecord)jt.next();
13542                if (cpr.clients.size() != 0) {
13543                    Iterator<ProcessRecord> kt = cpr.clients.iterator();
13544                    while (kt.hasNext() && adj > FOREGROUND_APP_ADJ) {
13545                        ProcessRecord client = kt.next();
13546                        if (client == app) {
13547                            // Being our own client is not interesting.
13548                            continue;
13549                        }
13550                        int myHiddenAdj = hiddenAdj;
13551                        if (myHiddenAdj > client.hiddenAdj) {
13552                            if (client.hiddenAdj > FOREGROUND_APP_ADJ) {
13553                                myHiddenAdj = client.hiddenAdj;
13554                            } else {
13555                                myHiddenAdj = FOREGROUND_APP_ADJ;
13556                            }
13557                        }
13558                        int clientAdj = computeOomAdjLocked(
13559                            client, myHiddenAdj, TOP_APP, true);
13560                        if (adj > clientAdj) {
13561                            adj = clientAdj > FOREGROUND_APP_ADJ
13562                                    ? clientAdj : FOREGROUND_APP_ADJ;
13563                            if (!client.hidden) {
13564                                app.hidden = false;
13565                            }
13566                            app.adjType = "provider";
13567                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
13568                                    .REASON_PROVIDER_IN_USE;
13569                            app.adjSource = client;
13570                            app.adjTarget = cpr.info.name;
13571                        }
13572                        if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
13573                            schedGroup = Process.THREAD_GROUP_DEFAULT;
13574                        }
13575                    }
13576                }
13577                // If the provider has external (non-framework) process
13578                // dependencies, ensure that its adjustment is at least
13579                // FOREGROUND_APP_ADJ.
13580                if (cpr.externals != 0) {
13581                    if (adj > FOREGROUND_APP_ADJ) {
13582                        adj = FOREGROUND_APP_ADJ;
13583                        schedGroup = Process.THREAD_GROUP_DEFAULT;
13584                        app.hidden = false;
13585                        app.adjType = "provider";
13586                        app.adjTarget = cpr.info.name;
13587                    }
13588                }
13589            }
13590        }
13591
13592        app.curRawAdj = adj;
13593
13594        //Log.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
13595        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
13596        if (adj > app.maxAdj) {
13597            adj = app.maxAdj;
13598            if (app.maxAdj <= VISIBLE_APP_ADJ) {
13599                schedGroup = Process.THREAD_GROUP_DEFAULT;
13600            }
13601        }
13602
13603        app.curAdj = adj;
13604        app.curSchedGroup = schedGroup;
13605
13606        return adj;
13607    }
13608
13609    /**
13610     * Ask a given process to GC right now.
13611     */
13612    final void performAppGcLocked(ProcessRecord app) {
13613        try {
13614            app.lastRequestedGc = SystemClock.uptimeMillis();
13615            if (app.thread != null) {
13616                if (app.reportLowMemory) {
13617                    app.reportLowMemory = false;
13618                    app.thread.scheduleLowMemory();
13619                } else {
13620                    app.thread.processInBackground();
13621                }
13622            }
13623        } catch (Exception e) {
13624            // whatever.
13625        }
13626    }
13627
13628    /**
13629     * Returns true if things are idle enough to perform GCs.
13630     */
13631    private final boolean canGcNow() {
13632        return mParallelBroadcasts.size() == 0
13633                && mOrderedBroadcasts.size() == 0
13634                && (mSleeping || (mResumedActivity != null &&
13635                        mResumedActivity.idle));
13636    }
13637
13638    /**
13639     * Perform GCs on all processes that are waiting for it, but only
13640     * if things are idle.
13641     */
13642    final void performAppGcsLocked() {
13643        final int N = mProcessesToGc.size();
13644        if (N <= 0) {
13645            return;
13646        }
13647        if (canGcNow()) {
13648            while (mProcessesToGc.size() > 0) {
13649                ProcessRecord proc = mProcessesToGc.remove(0);
13650                if (proc.curRawAdj > VISIBLE_APP_ADJ || proc.reportLowMemory) {
13651                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
13652                            <= SystemClock.uptimeMillis()) {
13653                        // To avoid spamming the system, we will GC processes one
13654                        // at a time, waiting a few seconds between each.
13655                        performAppGcLocked(proc);
13656                        scheduleAppGcsLocked();
13657                        return;
13658                    } else {
13659                        // It hasn't been long enough since we last GCed this
13660                        // process...  put it in the list to wait for its time.
13661                        addProcessToGcListLocked(proc);
13662                        break;
13663                    }
13664                }
13665            }
13666
13667            scheduleAppGcsLocked();
13668        }
13669    }
13670
13671    /**
13672     * If all looks good, perform GCs on all processes waiting for them.
13673     */
13674    final void performAppGcsIfAppropriateLocked() {
13675        if (canGcNow()) {
13676            performAppGcsLocked();
13677            return;
13678        }
13679        // Still not idle, wait some more.
13680        scheduleAppGcsLocked();
13681    }
13682
13683    /**
13684     * Schedule the execution of all pending app GCs.
13685     */
13686    final void scheduleAppGcsLocked() {
13687        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
13688
13689        if (mProcessesToGc.size() > 0) {
13690            // Schedule a GC for the time to the next process.
13691            ProcessRecord proc = mProcessesToGc.get(0);
13692            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
13693
13694            long when = mProcessesToGc.get(0).lastRequestedGc + GC_MIN_INTERVAL;
13695            long now = SystemClock.uptimeMillis();
13696            if (when < (now+GC_TIMEOUT)) {
13697                when = now + GC_TIMEOUT;
13698            }
13699            mHandler.sendMessageAtTime(msg, when);
13700        }
13701    }
13702
13703    /**
13704     * Add a process to the array of processes waiting to be GCed.  Keeps the
13705     * list in sorted order by the last GC time.  The process can't already be
13706     * on the list.
13707     */
13708    final void addProcessToGcListLocked(ProcessRecord proc) {
13709        boolean added = false;
13710        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
13711            if (mProcessesToGc.get(i).lastRequestedGc <
13712                    proc.lastRequestedGc) {
13713                added = true;
13714                mProcessesToGc.add(i+1, proc);
13715                break;
13716            }
13717        }
13718        if (!added) {
13719            mProcessesToGc.add(0, proc);
13720        }
13721    }
13722
13723    /**
13724     * Set up to ask a process to GC itself.  This will either do it
13725     * immediately, or put it on the list of processes to gc the next
13726     * time things are idle.
13727     */
13728    final void scheduleAppGcLocked(ProcessRecord app) {
13729        long now = SystemClock.uptimeMillis();
13730        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
13731            return;
13732        }
13733        if (!mProcessesToGc.contains(app)) {
13734            addProcessToGcListLocked(app);
13735            scheduleAppGcsLocked();
13736        }
13737    }
13738
13739    private final boolean updateOomAdjLocked(
13740        ProcessRecord app, int hiddenAdj, ProcessRecord TOP_APP) {
13741        app.hiddenAdj = hiddenAdj;
13742
13743        if (app.thread == null) {
13744            return true;
13745        }
13746
13747        int adj = computeOomAdjLocked(app, hiddenAdj, TOP_APP, false);
13748
13749        if ((app.pid != 0 && app.pid != MY_PID) || Process.supportsProcesses()) {
13750            if (app.curRawAdj != app.setRawAdj) {
13751                if (app.curRawAdj > FOREGROUND_APP_ADJ
13752                        && app.setRawAdj <= FOREGROUND_APP_ADJ) {
13753                    // If this app is transitioning from foreground to
13754                    // non-foreground, have it do a gc.
13755                    scheduleAppGcLocked(app);
13756                } else if (app.curRawAdj >= HIDDEN_APP_MIN_ADJ
13757                        && app.setRawAdj < HIDDEN_APP_MIN_ADJ) {
13758                    // Likewise do a gc when an app is moving in to the
13759                    // background (such as a service stopping).
13760                    scheduleAppGcLocked(app);
13761                }
13762                app.setRawAdj = app.curRawAdj;
13763            }
13764            if (adj != app.setAdj) {
13765                if (Process.setOomAdj(app.pid, adj)) {
13766                    if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Log.v(
13767                        TAG, "Set app " + app.processName +
13768                        " oom adj to " + adj);
13769                    app.setAdj = adj;
13770                } else {
13771                    return false;
13772                }
13773            }
13774            if (app.setSchedGroup != app.curSchedGroup) {
13775                app.setSchedGroup = app.curSchedGroup;
13776                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Log.v(TAG,
13777                        "Setting process group of " + app.processName
13778                        + " to " + app.curSchedGroup);
13779                if (true) {
13780                    long oldId = Binder.clearCallingIdentity();
13781                    try {
13782                        Process.setProcessGroup(app.pid, app.curSchedGroup);
13783                    } catch (Exception e) {
13784                        Log.w(TAG, "Failed setting process group of " + app.pid
13785                                + " to " + app.curSchedGroup);
13786                        e.printStackTrace();
13787                    } finally {
13788                        Binder.restoreCallingIdentity(oldId);
13789                    }
13790                }
13791                if (false) {
13792                    if (app.thread != null) {
13793                        try {
13794                            app.thread.setSchedulingGroup(app.curSchedGroup);
13795                        } catch (RemoteException e) {
13796                        }
13797                    }
13798                }
13799            }
13800        }
13801
13802        return true;
13803    }
13804
13805    private final HistoryRecord resumedAppLocked() {
13806        HistoryRecord resumedActivity = mResumedActivity;
13807        if (resumedActivity == null || resumedActivity.app == null) {
13808            resumedActivity = mPausingActivity;
13809            if (resumedActivity == null || resumedActivity.app == null) {
13810                resumedActivity = topRunningActivityLocked(null);
13811            }
13812        }
13813        return resumedActivity;
13814    }
13815
13816    private final boolean updateOomAdjLocked(ProcessRecord app) {
13817        final HistoryRecord TOP_ACT = resumedAppLocked();
13818        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13819        int curAdj = app.curAdj;
13820        final boolean wasHidden = app.curAdj >= HIDDEN_APP_MIN_ADJ
13821            && app.curAdj <= HIDDEN_APP_MAX_ADJ;
13822
13823        mAdjSeq++;
13824
13825        final boolean res = updateOomAdjLocked(app, app.hiddenAdj, TOP_APP);
13826        if (res) {
13827            final boolean nowHidden = app.curAdj >= HIDDEN_APP_MIN_ADJ
13828                && app.curAdj <= HIDDEN_APP_MAX_ADJ;
13829            if (nowHidden != wasHidden) {
13830                // Changed to/from hidden state, so apps after it in the LRU
13831                // list may also be changed.
13832                updateOomAdjLocked();
13833            }
13834        }
13835        return res;
13836    }
13837
13838    private final boolean updateOomAdjLocked() {
13839        boolean didOomAdj = true;
13840        final HistoryRecord TOP_ACT = resumedAppLocked();
13841        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13842
13843        if (false) {
13844            RuntimeException e = new RuntimeException();
13845            e.fillInStackTrace();
13846            Log.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
13847        }
13848
13849        mAdjSeq++;
13850
13851        // First try updating the OOM adjustment for each of the
13852        // application processes based on their current state.
13853        int i = mLruProcesses.size();
13854        int curHiddenAdj = HIDDEN_APP_MIN_ADJ;
13855        while (i > 0) {
13856            i--;
13857            ProcessRecord app = mLruProcesses.get(i);
13858            //Log.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj);
13859            if (updateOomAdjLocked(app, curHiddenAdj, TOP_APP)) {
13860                if (curHiddenAdj < EMPTY_APP_ADJ
13861                    && app.curAdj == curHiddenAdj) {
13862                    curHiddenAdj++;
13863                }
13864            } else {
13865                didOomAdj = false;
13866            }
13867        }
13868
13869        // If we return false, we will fall back on killing processes to
13870        // have a fixed limit.  Do this if a limit has been requested; else
13871        // only return false if one of the adjustments failed.
13872        return ENFORCE_PROCESS_LIMIT || mProcessLimit > 0 ? false : didOomAdj;
13873    }
13874
13875    private final void trimApplications() {
13876        synchronized (this) {
13877            int i;
13878
13879            // First remove any unused application processes whose package
13880            // has been removed.
13881            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
13882                final ProcessRecord app = mRemovedProcesses.get(i);
13883                if (app.activities.size() == 0
13884                        && app.curReceiver == null && app.services.size() == 0) {
13885                    Log.i(
13886                        TAG, "Exiting empty application process "
13887                        + app.processName + " ("
13888                        + (app.thread != null ? app.thread.asBinder() : null)
13889                        + ")\n");
13890                    if (app.pid > 0 && app.pid != MY_PID) {
13891                        Process.killProcess(app.pid);
13892                    } else {
13893                        try {
13894                            app.thread.scheduleExit();
13895                        } catch (Exception e) {
13896                            // Ignore exceptions.
13897                        }
13898                    }
13899                    cleanUpApplicationRecordLocked(app, false, -1);
13900                    mRemovedProcesses.remove(i);
13901
13902                    if (app.persistent) {
13903                        if (app.persistent) {
13904                            addAppLocked(app.info);
13905                        }
13906                    }
13907                }
13908            }
13909
13910            // Now try updating the OOM adjustment for each of the
13911            // application processes based on their current state.
13912            // If the setOomAdj() API is not supported, then go with our
13913            // back-up plan...
13914            if (!updateOomAdjLocked()) {
13915
13916                // Count how many processes are running services.
13917                int numServiceProcs = 0;
13918                for (i=mLruProcesses.size()-1; i>=0; i--) {
13919                    final ProcessRecord app = mLruProcesses.get(i);
13920
13921                    if (app.persistent || app.services.size() != 0
13922                            || app.curReceiver != null
13923                            || app.persistentActivities > 0) {
13924                        // Don't count processes holding services against our
13925                        // maximum process count.
13926                        if (localLOGV) Log.v(
13927                            TAG, "Not trimming app " + app + " with services: "
13928                            + app.services);
13929                        numServiceProcs++;
13930                    }
13931                }
13932
13933                int curMaxProcs = mProcessLimit;
13934                if (curMaxProcs <= 0) curMaxProcs = MAX_PROCESSES;
13935                if (mAlwaysFinishActivities) {
13936                    curMaxProcs = 1;
13937                }
13938                curMaxProcs += numServiceProcs;
13939
13940                // Quit as many processes as we can to get down to the desired
13941                // process count.  First remove any processes that no longer
13942                // have activites running in them.
13943                for (   i=0;
13944                        i<mLruProcesses.size()
13945                            && mLruProcesses.size() > curMaxProcs;
13946                        i++) {
13947                    final ProcessRecord app = mLruProcesses.get(i);
13948                    // Quit an application only if it is not currently
13949                    // running any activities.
13950                    if (!app.persistent && app.activities.size() == 0
13951                            && app.curReceiver == null && app.services.size() == 0) {
13952                        Log.i(
13953                            TAG, "Exiting empty application process "
13954                            + app.processName + " ("
13955                            + (app.thread != null ? app.thread.asBinder() : null)
13956                            + ")\n");
13957                        if (app.pid > 0 && app.pid != MY_PID) {
13958                            Process.killProcess(app.pid);
13959                        } else {
13960                            try {
13961                                app.thread.scheduleExit();
13962                            } catch (Exception e) {
13963                                // Ignore exceptions.
13964                            }
13965                        }
13966                        // todo: For now we assume the application is not buggy
13967                        // or evil, and will quit as a result of our request.
13968                        // Eventually we need to drive this off of the death
13969                        // notification, and kill the process if it takes too long.
13970                        cleanUpApplicationRecordLocked(app, false, i);
13971                        i--;
13972                    }
13973                }
13974
13975                // If we still have too many processes, now from the least
13976                // recently used process we start finishing activities.
13977                if (Config.LOGV) Log.v(
13978                    TAG, "*** NOW HAVE " + mLruProcesses.size() +
13979                    " of " + curMaxProcs + " processes");
13980                for (   i=0;
13981                        i<mLruProcesses.size()
13982                            && mLruProcesses.size() > curMaxProcs;
13983                        i++) {
13984                    final ProcessRecord app = mLruProcesses.get(i);
13985                    // Quit the application only if we have a state saved for
13986                    // all of its activities.
13987                    boolean canQuit = !app.persistent && app.curReceiver == null
13988                        && app.services.size() == 0
13989                        && app.persistentActivities == 0;
13990                    int NUMA = app.activities.size();
13991                    int j;
13992                    if (Config.LOGV) Log.v(
13993                        TAG, "Looking to quit " + app.processName);
13994                    for (j=0; j<NUMA && canQuit; j++) {
13995                        HistoryRecord r = (HistoryRecord)app.activities.get(j);
13996                        if (Config.LOGV) Log.v(
13997                            TAG, "  " + r.intent.getComponent().flattenToShortString()
13998                            + ": frozen=" + r.haveState + ", visible=" + r.visible);
13999                        canQuit = (r.haveState || !r.stateNotNeeded)
14000                                && !r.visible && r.stopped;
14001                    }
14002                    if (canQuit) {
14003                        // Finish all of the activities, and then the app itself.
14004                        for (j=0; j<NUMA; j++) {
14005                            HistoryRecord r = (HistoryRecord)app.activities.get(j);
14006                            if (!r.finishing) {
14007                                destroyActivityLocked(r, false);
14008                            }
14009                            r.resultTo = null;
14010                        }
14011                        Log.i(TAG, "Exiting application process "
14012                              + app.processName + " ("
14013                              + (app.thread != null ? app.thread.asBinder() : null)
14014                              + ")\n");
14015                        if (app.pid > 0 && app.pid != MY_PID) {
14016                            Process.killProcess(app.pid);
14017                        } else {
14018                            try {
14019                                app.thread.scheduleExit();
14020                            } catch (Exception e) {
14021                                // Ignore exceptions.
14022                            }
14023                        }
14024                        // todo: For now we assume the application is not buggy
14025                        // or evil, and will quit as a result of our request.
14026                        // Eventually we need to drive this off of the death
14027                        // notification, and kill the process if it takes too long.
14028                        cleanUpApplicationRecordLocked(app, false, i);
14029                        i--;
14030                        //dump();
14031                    }
14032                }
14033
14034            }
14035
14036            int curMaxActivities = MAX_ACTIVITIES;
14037            if (mAlwaysFinishActivities) {
14038                curMaxActivities = 1;
14039            }
14040
14041            // Finally, if there are too many activities now running, try to
14042            // finish as many as we can to get back down to the limit.
14043            for (   i=0;
14044                    i<mLRUActivities.size()
14045                        && mLRUActivities.size() > curMaxActivities;
14046                    i++) {
14047                final HistoryRecord r
14048                    = (HistoryRecord)mLRUActivities.get(i);
14049
14050                // We can finish this one if we have its icicle saved and
14051                // it is not persistent.
14052                if ((r.haveState || !r.stateNotNeeded) && !r.visible
14053                        && r.stopped && !r.persistent && !r.finishing) {
14054                    final int origSize = mLRUActivities.size();
14055                    destroyActivityLocked(r, true);
14056
14057                    // This will remove it from the LRU list, so keep
14058                    // our index at the same value.  Note that this check to
14059                    // see if the size changes is just paranoia -- if
14060                    // something unexpected happens, we don't want to end up
14061                    // in an infinite loop.
14062                    if (origSize > mLRUActivities.size()) {
14063                        i--;
14064                    }
14065                }
14066            }
14067        }
14068    }
14069
14070    /** This method sends the specified signal to each of the persistent apps */
14071    public void signalPersistentProcesses(int sig) throws RemoteException {
14072        if (sig != Process.SIGNAL_USR1) {
14073            throw new SecurityException("Only SIGNAL_USR1 is allowed");
14074        }
14075
14076        synchronized (this) {
14077            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
14078                    != PackageManager.PERMISSION_GRANTED) {
14079                throw new SecurityException("Requires permission "
14080                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
14081            }
14082
14083            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
14084                ProcessRecord r = mLruProcesses.get(i);
14085                if (r.thread != null && r.persistent) {
14086                    Process.sendSignal(r.pid, sig);
14087                }
14088            }
14089        }
14090    }
14091
14092    public boolean profileControl(String process, boolean start,
14093            String path, ParcelFileDescriptor fd) throws RemoteException {
14094
14095        try {
14096            synchronized (this) {
14097                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
14098                // its own permission.
14099                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14100                        != PackageManager.PERMISSION_GRANTED) {
14101                    throw new SecurityException("Requires permission "
14102                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
14103                }
14104
14105                if (start && fd == null) {
14106                    throw new IllegalArgumentException("null fd");
14107                }
14108
14109                ProcessRecord proc = null;
14110                try {
14111                    int pid = Integer.parseInt(process);
14112                    synchronized (mPidsSelfLocked) {
14113                        proc = mPidsSelfLocked.get(pid);
14114                    }
14115                } catch (NumberFormatException e) {
14116                }
14117
14118                if (proc == null) {
14119                    HashMap<String, SparseArray<ProcessRecord>> all
14120                            = mProcessNames.getMap();
14121                    SparseArray<ProcessRecord> procs = all.get(process);
14122                    if (procs != null && procs.size() > 0) {
14123                        proc = procs.valueAt(0);
14124                    }
14125                }
14126
14127                if (proc == null || proc.thread == null) {
14128                    throw new IllegalArgumentException("Unknown process: " + process);
14129                }
14130
14131                boolean isSecure = "1".equals(SystemProperties.get(SYSTEM_SECURE, "0"));
14132                if (isSecure) {
14133                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
14134                        throw new SecurityException("Process not debuggable: " + proc);
14135                    }
14136                }
14137
14138                proc.thread.profilerControl(start, path, fd);
14139                fd = null;
14140                return true;
14141            }
14142        } catch (RemoteException e) {
14143            throw new IllegalStateException("Process disappeared");
14144        } finally {
14145            if (fd != null) {
14146                try {
14147                    fd.close();
14148                } catch (IOException e) {
14149                }
14150            }
14151        }
14152    }
14153
14154    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
14155    public void monitor() {
14156        synchronized (this) { }
14157    }
14158}
14159