ActivityManagerService.java revision 23085b781e145ed684e7270af1d5ced6800b8eff
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.PackageInfo;
65import android.content.pm.PackageManager;
66import android.content.pm.PathPermission;
67import android.content.pm.ProviderInfo;
68import android.content.pm.ResolveInfo;
69import android.content.pm.ServiceInfo;
70import android.content.res.Configuration;
71import android.graphics.Bitmap;
72import android.net.Uri;
73import android.os.Binder;
74import android.os.Build;
75import android.os.Bundle;
76import android.os.Debug;
77import android.os.DropBoxManager;
78import android.os.Environment;
79import android.os.FileObserver;
80import android.os.FileUtils;
81import android.os.Handler;
82import android.os.IBinder;
83import android.os.IPermissionController;
84import android.os.Looper;
85import android.os.Message;
86import android.os.Parcel;
87import android.os.ParcelFileDescriptor;
88import android.os.PowerManager;
89import android.os.Process;
90import android.os.RemoteCallbackList;
91import android.os.RemoteException;
92import android.os.ServiceManager;
93import android.os.SystemClock;
94import android.os.SystemProperties;
95import android.provider.Checkin;
96import android.provider.Settings;
97import android.text.TextUtils;
98import android.util.Config;
99import android.util.EventLog;
100import android.util.Log;
101import android.util.PrintWriterPrinter;
102import android.util.SparseArray;
103import android.view.Gravity;
104import android.view.LayoutInflater;
105import android.view.View;
106import android.view.WindowManager;
107import android.view.WindowManagerPolicy;
108
109import java.io.File;
110import java.io.FileDescriptor;
111import java.io.FileInputStream;
112import java.io.FileNotFoundException;
113import java.io.IOException;
114import java.io.PrintWriter;
115import java.lang.IllegalStateException;
116import java.lang.ref.WeakReference;
117import java.util.ArrayList;
118import java.util.HashMap;
119import java.util.HashSet;
120import java.util.Iterator;
121import java.util.List;
122import java.util.Locale;
123import java.util.Map;
124
125public final class ActivityManagerService extends ActivityManagerNative implements Watchdog.Monitor {
126    static final String TAG = "ActivityManager";
127    static final boolean DEBUG = false;
128    static final boolean localLOGV = DEBUG ? Config.LOGD : Config.LOGV;
129    static final boolean DEBUG_SWITCH = localLOGV || false;
130    static final boolean DEBUG_TASKS = localLOGV || false;
131    static final boolean DEBUG_PAUSE = localLOGV || false;
132    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
133    static final boolean DEBUG_TRANSITION = localLOGV || false;
134    static final boolean DEBUG_BROADCAST = localLOGV || false;
135    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
136    static final boolean DEBUG_SERVICE = localLOGV || false;
137    static final boolean DEBUG_VISBILITY = localLOGV || false;
138    static final boolean DEBUG_PROCESSES = localLOGV || false;
139    static final boolean DEBUG_PROVIDER = localLOGV || false;
140    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
141    static final boolean DEBUG_RESULTS = localLOGV || false;
142    static final boolean DEBUG_BACKUP = localLOGV || false;
143    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
144    static final boolean VALIDATE_TOKENS = false;
145    static final boolean SHOW_ACTIVITY_START_TIME = true;
146
147    // Control over CPU and battery monitoring.
148    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
149    static final boolean MONITOR_CPU_USAGE = true;
150    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
151    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
152    static final boolean MONITOR_THREAD_CPU_USAGE = false;
153
154    // The flags that are set for all calls we make to the package manager.
155    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
156
157    private static final String SYSTEM_SECURE = "ro.secure";
158
159    // This is the maximum number of application processes we would like
160    // to have running.  Due to the asynchronous nature of things, we can
161    // temporarily go beyond this limit.
162    static final int MAX_PROCESSES = 2;
163
164    // Set to false to leave processes running indefinitely, relying on
165    // the kernel killing them as resources are required.
166    static final boolean ENFORCE_PROCESS_LIMIT = false;
167
168    // This is the maximum number of activities that we would like to have
169    // running at a given time.
170    static final int MAX_ACTIVITIES = 20;
171
172    // Maximum number of recent tasks that we can remember.
173    static final int MAX_RECENT_TASKS = 20;
174
175    // Amount of time after a call to stopAppSwitches() during which we will
176    // prevent further untrusted switches from happening.
177    static final long APP_SWITCH_DELAY_TIME = 5*1000;
178
179    // How long until we reset a task when the user returns to it.  Currently
180    // 30 minutes.
181    static final long ACTIVITY_INACTIVE_RESET_TIME = 1000*60*30;
182
183    // Set to true to disable the icon that is shown while a new activity
184    // is being started.
185    static final boolean SHOW_APP_STARTING_ICON = true;
186
187    // How long we wait until giving up on the last activity to pause.  This
188    // is short because it directly impacts the responsiveness of starting the
189    // next activity.
190    static final int PAUSE_TIMEOUT = 500;
191
192    /**
193     * How long we can hold the launch wake lock before giving up.
194     */
195    static final int LAUNCH_TIMEOUT = 10*1000;
196
197    // How long we wait for a launched process to attach to the activity manager
198    // before we decide it's never going to come up for real.
199    static final int PROC_START_TIMEOUT = 10*1000;
200
201    // How long we wait until giving up on the last activity telling us it
202    // is idle.
203    static final int IDLE_TIMEOUT = 10*1000;
204
205    // How long to wait after going idle before forcing apps to GC.
206    static final int GC_TIMEOUT = 5*1000;
207
208    // The minimum amount of time between successive GC requests for a process.
209    static final int GC_MIN_INTERVAL = 60*1000;
210
211    // How long we wait until giving up on an activity telling us it has
212    // finished destroying itself.
213    static final int DESTROY_TIMEOUT = 10*1000;
214
215    // How long we allow a receiver to run before giving up on it.
216    static final int BROADCAST_TIMEOUT = 10*1000;
217
218    // How long we wait for a service to finish executing.
219    static final int SERVICE_TIMEOUT = 20*1000;
220
221    // How long a service needs to be running until restarting its process
222    // is no longer considered to be a relaunch of the service.
223    static final int SERVICE_RESTART_DURATION = 5*1000;
224
225    // How long a service needs to be running until it will start back at
226    // SERVICE_RESTART_DURATION after being killed.
227    static final int SERVICE_RESET_RUN_DURATION = 60*1000;
228
229    // Multiplying factor to increase restart duration time by, for each time
230    // a service is killed before it has run for SERVICE_RESET_RUN_DURATION.
231    static final int SERVICE_RESTART_DURATION_FACTOR = 4;
232
233    // The minimum amount of time between restarting services that we allow.
234    // That is, when multiple services are restarting, we won't allow each
235    // to restart less than this amount of time from the last one.
236    static final int SERVICE_MIN_RESTART_TIME_BETWEEN = 10*1000;
237
238    // Maximum amount of time for there to be no activity on a service before
239    // we consider it non-essential and allow its process to go on the
240    // LRU background list.
241    static final int MAX_SERVICE_INACTIVITY = 30*60*1000;
242
243    // How long we wait until we timeout on key dispatching.
244    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
245
246    // The minimum time we allow between crashes, for us to consider this
247    // application to be bad and stop and its services and reject broadcasts.
248    static final int MIN_CRASH_INTERVAL = 60*1000;
249
250    // How long we wait until we timeout on key dispatching during instrumentation.
251    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
252
253    // OOM adjustments for processes in various states:
254
255    // This is a process without anything currently running in it.  Definitely
256    // the first to go! Value set in system/rootdir/init.rc on startup.
257    // This value is initalized in the constructor, careful when refering to
258    // this static variable externally.
259    static final int EMPTY_APP_ADJ;
260
261    // This is a process only hosting activities that are not visible,
262    // so it can be killed without any disruption. Value set in
263    // system/rootdir/init.rc on startup.
264    static final int HIDDEN_APP_MAX_ADJ;
265    static int HIDDEN_APP_MIN_ADJ;
266
267    // This is a process holding the home application -- we want to try
268    // avoiding killing it, even if it would normally be in the background,
269    // because the user interacts with it so much.
270    static final int HOME_APP_ADJ;
271
272    // This is a process currently hosting a backup operation.  Killing it
273    // is not entirely fatal but is generally a bad idea.
274    static final int BACKUP_APP_ADJ;
275
276    // This is a process holding a secondary server -- killing it will not
277    // have much of an impact as far as the user is concerned. Value set in
278    // system/rootdir/init.rc on startup.
279    static final int SECONDARY_SERVER_ADJ;
280
281    // This is a process only hosting activities that are visible to the
282    // user, so we'd prefer they don't disappear. Value set in
283    // system/rootdir/init.rc on startup.
284    static final int VISIBLE_APP_ADJ;
285
286    // This is the process running the current foreground app.  We'd really
287    // rather not kill it! Value set in system/rootdir/init.rc on startup.
288    static final int FOREGROUND_APP_ADJ;
289
290    // This is a process running a core server, such as telephony.  Definitely
291    // don't want to kill it, but doing so is not completely fatal.
292    static final int CORE_SERVER_ADJ = -12;
293
294    // The system process runs at the default adjustment.
295    static final int SYSTEM_ADJ = -16;
296
297    // Memory pages are 4K.
298    static final int PAGE_SIZE = 4*1024;
299
300    // System property defining error report receiver for system apps
301    static final String SYSTEM_APPS_ERROR_RECEIVER_PROPERTY = "ro.error.receiver.system.apps";
302
303    // System property defining default error report receiver
304    static final String DEFAULT_ERROR_RECEIVER_PROPERTY = "ro.error.receiver.default";
305
306    // Corresponding memory levels for above adjustments.
307    static final int EMPTY_APP_MEM;
308    static final int HIDDEN_APP_MEM;
309    static final int HOME_APP_MEM;
310    static final int BACKUP_APP_MEM;
311    static final int SECONDARY_SERVER_MEM;
312    static final int VISIBLE_APP_MEM;
313    static final int FOREGROUND_APP_MEM;
314
315    // The minimum number of hidden apps we want to be able to keep around,
316    // without empty apps being able to push them out of memory.
317    static final int MIN_HIDDEN_APPS = 2;
318
319    // We put empty content processes after any hidden processes that have
320    // been idle for less than 30 seconds.
321    static final long CONTENT_APP_IDLE_OFFSET = 30*1000;
322
323    // We put empty content processes after any hidden processes that have
324    // been idle for less than 60 seconds.
325    static final long EMPTY_APP_IDLE_OFFSET = 60*1000;
326
327    static {
328        // These values are set in system/rootdir/init.rc on startup.
329        FOREGROUND_APP_ADJ =
330            Integer.valueOf(SystemProperties.get("ro.FOREGROUND_APP_ADJ"));
331        VISIBLE_APP_ADJ =
332            Integer.valueOf(SystemProperties.get("ro.VISIBLE_APP_ADJ"));
333        SECONDARY_SERVER_ADJ =
334            Integer.valueOf(SystemProperties.get("ro.SECONDARY_SERVER_ADJ"));
335        BACKUP_APP_ADJ =
336            Integer.valueOf(SystemProperties.get("ro.BACKUP_APP_ADJ"));
337        HOME_APP_ADJ =
338            Integer.valueOf(SystemProperties.get("ro.HOME_APP_ADJ"));
339        HIDDEN_APP_MIN_ADJ =
340            Integer.valueOf(SystemProperties.get("ro.HIDDEN_APP_MIN_ADJ"));
341        EMPTY_APP_ADJ =
342            Integer.valueOf(SystemProperties.get("ro.EMPTY_APP_ADJ"));
343        HIDDEN_APP_MAX_ADJ = EMPTY_APP_ADJ-1;
344        FOREGROUND_APP_MEM =
345            Integer.valueOf(SystemProperties.get("ro.FOREGROUND_APP_MEM"))*PAGE_SIZE;
346        VISIBLE_APP_MEM =
347            Integer.valueOf(SystemProperties.get("ro.VISIBLE_APP_MEM"))*PAGE_SIZE;
348        SECONDARY_SERVER_MEM =
349            Integer.valueOf(SystemProperties.get("ro.SECONDARY_SERVER_MEM"))*PAGE_SIZE;
350        BACKUP_APP_MEM =
351            Integer.valueOf(SystemProperties.get("ro.BACKUP_APP_MEM"))*PAGE_SIZE;
352        HOME_APP_MEM =
353            Integer.valueOf(SystemProperties.get("ro.HOME_APP_MEM"))*PAGE_SIZE;
354        HIDDEN_APP_MEM =
355            Integer.valueOf(SystemProperties.get("ro.HIDDEN_APP_MEM"))*PAGE_SIZE;
356        EMPTY_APP_MEM =
357            Integer.valueOf(SystemProperties.get("ro.EMPTY_APP_MEM"))*PAGE_SIZE;
358    }
359
360    static final int MY_PID = Process.myPid();
361
362    static final String[] EMPTY_STRING_ARRAY = new String[0];
363
364    enum ActivityState {
365        INITIALIZING,
366        RESUMED,
367        PAUSING,
368        PAUSED,
369        STOPPING,
370        STOPPED,
371        FINISHING,
372        DESTROYING,
373        DESTROYED
374    }
375
376    /**
377     * The back history of all previous (and possibly still
378     * running) activities.  It contains HistoryRecord objects.
379     */
380    final ArrayList mHistory = new ArrayList();
381
382    /**
383     * Description of a request to start a new activity, which has been held
384     * due to app switches being disabled.
385     */
386    class PendingActivityLaunch {
387        HistoryRecord r;
388        HistoryRecord sourceRecord;
389        Uri[] grantedUriPermissions;
390        int grantedMode;
391        boolean onlyIfNeeded;
392    }
393
394    final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
395            = new ArrayList<PendingActivityLaunch>();
396
397    /**
398     * List of all active broadcasts that are to be executed immediately
399     * (without waiting for another broadcast to finish).  Currently this only
400     * contains broadcasts to registered receivers, to avoid spinning up
401     * a bunch of processes to execute IntentReceiver components.
402     */
403    final ArrayList<BroadcastRecord> mParallelBroadcasts
404            = new ArrayList<BroadcastRecord>();
405
406    /**
407     * List of all active broadcasts that are to be executed one at a time.
408     * The object at the top of the list is the currently activity broadcasts;
409     * those after it are waiting for the top to finish..
410     */
411    final ArrayList<BroadcastRecord> mOrderedBroadcasts
412            = new ArrayList<BroadcastRecord>();
413
414    /**
415     * Historical data of past broadcasts, for debugging.
416     */
417    static final int MAX_BROADCAST_HISTORY = 100;
418    final BroadcastRecord[] mBroadcastHistory
419            = new BroadcastRecord[MAX_BROADCAST_HISTORY];
420
421    /**
422     * Set when we current have a BROADCAST_INTENT_MSG in flight.
423     */
424    boolean mBroadcastsScheduled = false;
425
426    /**
427     * Set to indicate whether to issue an onUserLeaving callback when a
428     * newly launched activity is being brought in front of us.
429     */
430    boolean mUserLeaving = false;
431
432    /**
433     * When we are in the process of pausing an activity, before starting the
434     * next one, this variable holds the activity that is currently being paused.
435     */
436    HistoryRecord mPausingActivity = null;
437
438    /**
439     * Current activity that is resumed, or null if there is none.
440     */
441    HistoryRecord mResumedActivity = null;
442
443    /**
444     * Activity we have told the window manager to have key focus.
445     */
446    HistoryRecord mFocusedActivity = null;
447
448    /**
449     * This is the last activity that we put into the paused state.  This is
450     * used to determine if we need to do an activity transition while sleeping,
451     * when we normally hold the top activity paused.
452     */
453    HistoryRecord mLastPausedActivity = null;
454
455    /**
456     * List of activities that are waiting for a new activity
457     * to become visible before completing whatever operation they are
458     * supposed to do.
459     */
460    final ArrayList mWaitingVisibleActivities = new ArrayList();
461
462    /**
463     * List of activities that are ready to be stopped, but waiting
464     * for the next activity to settle down before doing so.  It contains
465     * HistoryRecord objects.
466     */
467    final ArrayList<HistoryRecord> mStoppingActivities
468            = new ArrayList<HistoryRecord>();
469
470    /**
471     * Animations that for the current transition have requested not to
472     * be considered for the transition animation.
473     */
474    final ArrayList<HistoryRecord> mNoAnimActivities
475            = new ArrayList<HistoryRecord>();
476
477    /**
478     * List of intents that were used to start the most recent tasks.
479     */
480    final ArrayList<TaskRecord> mRecentTasks
481            = new ArrayList<TaskRecord>();
482
483    /**
484     * List of activities that are ready to be finished, but waiting
485     * for the previous activity to settle down before doing so.  It contains
486     * HistoryRecord objects.
487     */
488    final ArrayList mFinishingActivities = new ArrayList();
489
490    /**
491     * All of the applications we currently have running organized by name.
492     * The keys are strings of the application package name (as
493     * returned by the package manager), and the keys are ApplicationRecord
494     * objects.
495     */
496    final ProcessMap<ProcessRecord> mProcessNames
497            = new ProcessMap<ProcessRecord>();
498
499    /**
500     * The last time that various processes have crashed.
501     */
502    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
503
504    /**
505     * Set of applications that we consider to be bad, and will reject
506     * incoming broadcasts from (which the user has no control over).
507     * Processes are added to this set when they have crashed twice within
508     * a minimum amount of time; they are removed from it when they are
509     * later restarted (hopefully due to some user action).  The value is the
510     * time it was added to the list.
511     */
512    final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>();
513
514    /**
515     * All of the processes we currently have running organized by pid.
516     * The keys are the pid running the application.
517     *
518     * <p>NOTE: This object is protected by its own lock, NOT the global
519     * activity manager lock!
520     */
521    final SparseArray<ProcessRecord> mPidsSelfLocked
522            = new SparseArray<ProcessRecord>();
523
524    /**
525     * All of the processes that have been forced to be foreground.  The key
526     * is the pid of the caller who requested it (we hold a death
527     * link on it).
528     */
529    abstract class ForegroundToken implements IBinder.DeathRecipient {
530        int pid;
531        IBinder token;
532    }
533    final SparseArray<ForegroundToken> mForegroundProcesses
534            = new SparseArray<ForegroundToken>();
535
536    /**
537     * List of records for processes that someone had tried to start before the
538     * system was ready.  We don't start them at that point, but ensure they
539     * are started by the time booting is complete.
540     */
541    final ArrayList<ProcessRecord> mProcessesOnHold
542            = new ArrayList<ProcessRecord>();
543
544    /**
545     * List of records for processes that we have started and are waiting
546     * for them to call back.  This is really only needed when running in
547     * single processes mode, in which case we do not have a unique pid for
548     * each process.
549     */
550    final ArrayList<ProcessRecord> mStartingProcesses
551            = new ArrayList<ProcessRecord>();
552
553    /**
554     * List of persistent applications that are in the process
555     * of being started.
556     */
557    final ArrayList<ProcessRecord> mPersistentStartingProcesses
558            = new ArrayList<ProcessRecord>();
559
560    /**
561     * Processes that are being forcibly torn down.
562     */
563    final ArrayList<ProcessRecord> mRemovedProcesses
564            = new ArrayList<ProcessRecord>();
565
566    /**
567     * List of running applications, sorted by recent usage.
568     * The first entry in the list is the least recently used.
569     * It contains ApplicationRecord objects.  This list does NOT include
570     * any persistent application records (since we never want to exit them).
571     */
572    final ArrayList<ProcessRecord> mLruProcesses
573            = new ArrayList<ProcessRecord>();
574
575    /**
576     * List of processes that should gc as soon as things are idle.
577     */
578    final ArrayList<ProcessRecord> mProcessesToGc
579            = new ArrayList<ProcessRecord>();
580
581    /**
582     * This is the process holding what we currently consider to be
583     * the "home" activity.
584     */
585    private ProcessRecord mHomeProcess;
586
587    /**
588     * List of running activities, sorted by recent usage.
589     * The first entry in the list is the least recently used.
590     * It contains HistoryRecord objects.
591     */
592    private final ArrayList mLRUActivities = new ArrayList();
593
594    /**
595     * Set of PendingResultRecord objects that are currently active.
596     */
597    final HashSet mPendingResultRecords = new HashSet();
598
599    /**
600     * Set of IntentSenderRecord objects that are currently active.
601     */
602    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
603            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
604
605    /**
606     * Intent broadcast that we have tried to start, but are
607     * waiting for its application's process to be created.  We only
608     * need one (instead of a list) because we always process broadcasts
609     * one at a time, so no others can be started while waiting for this
610     * one.
611     */
612    BroadcastRecord mPendingBroadcast = null;
613
614    /**
615     * Keeps track of all IIntentReceivers that have been registered for
616     * broadcasts.  Hash keys are the receiver IBinder, hash value is
617     * a ReceiverList.
618     */
619    final HashMap mRegisteredReceivers = new HashMap();
620
621    /**
622     * Resolver for broadcast intents to registered receivers.
623     * Holds BroadcastFilter (subclass of IntentFilter).
624     */
625    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
626            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
627        @Override
628        protected boolean allowFilterResult(
629                BroadcastFilter filter, List<BroadcastFilter> dest) {
630            IBinder target = filter.receiverList.receiver.asBinder();
631            for (int i=dest.size()-1; i>=0; i--) {
632                if (dest.get(i).receiverList.receiver.asBinder() == target) {
633                    return false;
634                }
635            }
636            return true;
637        }
638    };
639
640    /**
641     * State of all active sticky broadcasts.  Keys are the action of the
642     * sticky Intent, values are an ArrayList of all broadcasted intents with
643     * that action (which should usually be one).
644     */
645    final HashMap<String, ArrayList<Intent>> mStickyBroadcasts =
646            new HashMap<String, ArrayList<Intent>>();
647
648    /**
649     * All currently running services.
650     */
651    final HashMap<ComponentName, ServiceRecord> mServices =
652        new HashMap<ComponentName, ServiceRecord>();
653
654    /**
655     * All currently running services indexed by the Intent used to start them.
656     */
657    final HashMap<Intent.FilterComparison, ServiceRecord> mServicesByIntent =
658        new HashMap<Intent.FilterComparison, ServiceRecord>();
659
660    /**
661     * All currently bound service connections.  Keys are the IBinder of
662     * the client's IServiceConnection.
663     */
664    final HashMap<IBinder, ConnectionRecord> mServiceConnections
665            = new HashMap<IBinder, ConnectionRecord>();
666
667    /**
668     * List of services that we have been asked to start,
669     * but haven't yet been able to.  It is used to hold start requests
670     * while waiting for their corresponding application thread to get
671     * going.
672     */
673    final ArrayList<ServiceRecord> mPendingServices
674            = new ArrayList<ServiceRecord>();
675
676    /**
677     * List of services that are scheduled to restart following a crash.
678     */
679    final ArrayList<ServiceRecord> mRestartingServices
680            = new ArrayList<ServiceRecord>();
681
682    /**
683     * List of services that are in the process of being stopped.
684     */
685    final ArrayList<ServiceRecord> mStoppingServices
686            = new ArrayList<ServiceRecord>();
687
688    /**
689     * Backup/restore process management
690     */
691    String mBackupAppName = null;
692    BackupRecord mBackupTarget = null;
693
694    /**
695     * List of PendingThumbnailsRecord objects of clients who are still
696     * waiting to receive all of the thumbnails for a task.
697     */
698    final ArrayList mPendingThumbnails = new ArrayList();
699
700    /**
701     * List of HistoryRecord objects that have been finished and must
702     * still report back to a pending thumbnail receiver.
703     */
704    final ArrayList mCancelledThumbnails = new ArrayList();
705
706    /**
707     * All of the currently running global content providers.  Keys are a
708     * string containing the provider name and values are a
709     * ContentProviderRecord object containing the data about it.  Note
710     * that a single provider may be published under multiple names, so
711     * there may be multiple entries here for a single one in mProvidersByClass.
712     */
713    final HashMap mProvidersByName = new HashMap();
714
715    /**
716     * All of the currently running global content providers.  Keys are a
717     * string containing the provider's implementation class and values are a
718     * ContentProviderRecord object containing the data about it.
719     */
720    final HashMap mProvidersByClass = new HashMap();
721
722    /**
723     * List of content providers who have clients waiting for them.  The
724     * application is currently being launched and the provider will be
725     * removed from this list once it is published.
726     */
727    final ArrayList mLaunchingProviders = new ArrayList();
728
729    /**
730     * Global set of specific Uri permissions that have been granted.
731     */
732    final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions
733            = new SparseArray<HashMap<Uri, UriPermission>>();
734
735    /**
736     * Thread-local storage used to carry caller permissions over through
737     * indirect content-provider access.
738     * @see #ActivityManagerService.openContentUri()
739     */
740    private class Identity {
741        public int pid;
742        public int uid;
743
744        Identity(int _pid, int _uid) {
745            pid = _pid;
746            uid = _uid;
747        }
748    }
749    private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
750
751    /**
752     * All information we have collected about the runtime performance of
753     * any user id that can impact battery performance.
754     */
755    final BatteryStatsService mBatteryStatsService;
756
757    /**
758     * information about component usage
759     */
760    final UsageStatsService mUsageStatsService;
761
762    /**
763     * Current configuration information.  HistoryRecord objects are given
764     * a reference to this object to indicate which configuration they are
765     * currently running in, so this object must be kept immutable.
766     */
767    Configuration mConfiguration = new Configuration();
768
769    /**
770     * Hardware-reported OpenGLES version.
771     */
772    final int GL_ES_VERSION;
773
774    /**
775     * List of initialization arguments to pass to all processes when binding applications to them.
776     * For example, references to the commonly used services.
777     */
778    HashMap<String, IBinder> mAppBindArgs;
779
780    /**
781     * Temporary to avoid allocations.  Protected by main lock.
782     */
783    final StringBuilder mStringBuilder = new StringBuilder(256);
784
785    /**
786     * Used to control how we initialize the service.
787     */
788    boolean mStartRunning = false;
789    ComponentName mTopComponent;
790    String mTopAction;
791    String mTopData;
792    boolean mSystemReady = false;
793    boolean mBooting = false;
794    boolean mWaitingUpdate = false;
795    boolean mDidUpdate = false;
796
797    Context mContext;
798
799    int mFactoryTest;
800
801    boolean mCheckedForSetup;
802
803    /**
804     * The time at which we will allow normal application switches again,
805     * after a call to {@link #stopAppSwitches()}.
806     */
807    long mAppSwitchesAllowedTime;
808
809    /**
810     * This is set to true after the first switch after mAppSwitchesAllowedTime
811     * is set; any switches after that will clear the time.
812     */
813    boolean mDidAppSwitch;
814
815    /**
816     * Set while we are wanting to sleep, to prevent any
817     * activities from being started/resumed.
818     */
819    boolean mSleeping = false;
820
821    /**
822     * Set if we are shutting down the system, similar to sleeping.
823     */
824    boolean mShuttingDown = false;
825
826    /**
827     * Set when the system is going to sleep, until we have
828     * successfully paused the current activity and released our wake lock.
829     * At that point the system is allowed to actually sleep.
830     */
831    PowerManager.WakeLock mGoingToSleep;
832
833    /**
834     * We don't want to allow the device to go to sleep while in the process
835     * of launching an activity.  This is primarily to allow alarm intent
836     * receivers to launch an activity and get that to run before the device
837     * goes back to sleep.
838     */
839    PowerManager.WakeLock mLaunchingActivity;
840
841    /**
842     * Task identifier that activities are currently being started
843     * in.  Incremented each time a new task is created.
844     * todo: Replace this with a TokenSpace class that generates non-repeating
845     * integers that won't wrap.
846     */
847    int mCurTask = 1;
848
849    /**
850     * Current sequence id for oom_adj computation traversal.
851     */
852    int mAdjSeq = 0;
853
854    /**
855     * Set to true if the ANDROID_SIMPLE_PROCESS_MANAGEMENT envvar
856     * is set, indicating the user wants processes started in such a way
857     * that they can use ANDROID_PROCESS_WRAPPER and know what will be
858     * running in each process (thus no pre-initialized process, etc).
859     */
860    boolean mSimpleProcessManagement = false;
861
862    /**
863     * System monitoring: number of processes that died since the last
864     * N procs were started.
865     */
866    int[] mProcDeaths = new int[20];
867
868    /**
869     * This is set if we had to do a delayed dexopt of an app before launching
870     * it, to increasing the ANR timeouts in that case.
871     */
872    boolean mDidDexOpt;
873
874    String mDebugApp = null;
875    boolean mWaitForDebugger = false;
876    boolean mDebugTransient = false;
877    String mOrigDebugApp = null;
878    boolean mOrigWaitForDebugger = false;
879    boolean mAlwaysFinishActivities = false;
880    IActivityController mController = null;
881
882    final RemoteCallbackList<IActivityWatcher> mWatchers
883            = new RemoteCallbackList<IActivityWatcher>();
884
885    /**
886     * Callback of last caller to {@link #requestPss}.
887     */
888    Runnable mRequestPssCallback;
889
890    /**
891     * Remaining processes for which we are waiting results from the last
892     * call to {@link #requestPss}.
893     */
894    final ArrayList<ProcessRecord> mRequestPssList
895            = new ArrayList<ProcessRecord>();
896
897    /**
898     * Runtime statistics collection thread.  This object's lock is used to
899     * protect all related state.
900     */
901    final Thread mProcessStatsThread;
902
903    /**
904     * Used to collect process stats when showing not responding dialog.
905     * Protected by mProcessStatsThread.
906     */
907    final ProcessStats mProcessStats = new ProcessStats(
908            MONITOR_THREAD_CPU_USAGE);
909    long mLastCpuTime = 0;
910    long mLastWriteTime = 0;
911
912    long mInitialStartTime = 0;
913
914    /**
915     * Set to true after the system has finished booting.
916     */
917    boolean mBooted = false;
918
919    int mProcessLimit = 0;
920
921    WindowManagerService mWindowManager;
922
923    static ActivityManagerService mSelf;
924    static ActivityThread mSystemThread;
925
926    private final class AppDeathRecipient implements IBinder.DeathRecipient {
927        final ProcessRecord mApp;
928        final int mPid;
929        final IApplicationThread mAppThread;
930
931        AppDeathRecipient(ProcessRecord app, int pid,
932                IApplicationThread thread) {
933            if (localLOGV) Log.v(
934                TAG, "New death recipient " + this
935                + " for thread " + thread.asBinder());
936            mApp = app;
937            mPid = pid;
938            mAppThread = thread;
939        }
940
941        public void binderDied() {
942            if (localLOGV) Log.v(
943                TAG, "Death received in " + this
944                + " for thread " + mAppThread.asBinder());
945            removeRequestedPss(mApp);
946            synchronized(ActivityManagerService.this) {
947                appDiedLocked(mApp, mPid, mAppThread);
948            }
949        }
950    }
951
952    static final int SHOW_ERROR_MSG = 1;
953    static final int SHOW_NOT_RESPONDING_MSG = 2;
954    static final int SHOW_FACTORY_ERROR_MSG = 3;
955    static final int UPDATE_CONFIGURATION_MSG = 4;
956    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
957    static final int WAIT_FOR_DEBUGGER_MSG = 6;
958    static final int BROADCAST_INTENT_MSG = 7;
959    static final int BROADCAST_TIMEOUT_MSG = 8;
960    static final int PAUSE_TIMEOUT_MSG = 9;
961    static final int IDLE_TIMEOUT_MSG = 10;
962    static final int IDLE_NOW_MSG = 11;
963    static final int SERVICE_TIMEOUT_MSG = 12;
964    static final int UPDATE_TIME_ZONE = 13;
965    static final int SHOW_UID_ERROR_MSG = 14;
966    static final int IM_FEELING_LUCKY_MSG = 15;
967    static final int LAUNCH_TIMEOUT_MSG = 16;
968    static final int DESTROY_TIMEOUT_MSG = 17;
969    static final int SERVICE_ERROR_MSG = 18;
970    static final int RESUME_TOP_ACTIVITY_MSG = 19;
971    static final int PROC_START_TIMEOUT_MSG = 20;
972    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
973    static final int KILL_APPLICATION_MSG = 22;
974
975    AlertDialog mUidAlert;
976
977    final Handler mHandler = new Handler() {
978        //public Handler() {
979        //    if (localLOGV) Log.v(TAG, "Handler started!");
980        //}
981
982        public void handleMessage(Message msg) {
983            switch (msg.what) {
984            case SHOW_ERROR_MSG: {
985                HashMap data = (HashMap) msg.obj;
986                synchronized (ActivityManagerService.this) {
987                    ProcessRecord proc = (ProcessRecord)data.get("app");
988                    if (proc != null && proc.crashDialog != null) {
989                        Log.e(TAG, "App already has crash dialog: " + proc);
990                        return;
991                    }
992                    AppErrorResult res = (AppErrorResult) data.get("result");
993                    if (!mSleeping && !mShuttingDown) {
994                        Dialog d = new AppErrorDialog(mContext, res, proc);
995                        d.show();
996                        proc.crashDialog = d;
997                    } else {
998                        // The device is asleep, so just pretend that the user
999                        // saw a crash dialog and hit "force quit".
1000                        res.set(0);
1001                    }
1002                }
1003
1004                ensureBootCompleted();
1005            } break;
1006            case SHOW_NOT_RESPONDING_MSG: {
1007                synchronized (ActivityManagerService.this) {
1008                    HashMap data = (HashMap) msg.obj;
1009                    ProcessRecord proc = (ProcessRecord)data.get("app");
1010                    if (proc != null && proc.anrDialog != null) {
1011                        Log.e(TAG, "App already has anr dialog: " + proc);
1012                        return;
1013                    }
1014
1015                    broadcastIntentLocked(null, null, new Intent("android.intent.action.ANR"),
1016                            null, null, 0, null, null, null,
1017                            false, false, MY_PID, Process.SYSTEM_UID);
1018
1019                    Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1020                            mContext, proc, (HistoryRecord)data.get("activity"));
1021                    d.show();
1022                    proc.anrDialog = d;
1023                }
1024
1025                ensureBootCompleted();
1026            } break;
1027            case SHOW_FACTORY_ERROR_MSG: {
1028                Dialog d = new FactoryErrorDialog(
1029                    mContext, msg.getData().getCharSequence("msg"));
1030                d.show();
1031                ensureBootCompleted();
1032            } break;
1033            case UPDATE_CONFIGURATION_MSG: {
1034                final ContentResolver resolver = mContext.getContentResolver();
1035                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1036            } break;
1037            case GC_BACKGROUND_PROCESSES_MSG: {
1038                synchronized (ActivityManagerService.this) {
1039                    performAppGcsIfAppropriateLocked();
1040                }
1041            } break;
1042            case WAIT_FOR_DEBUGGER_MSG: {
1043                synchronized (ActivityManagerService.this) {
1044                    ProcessRecord app = (ProcessRecord)msg.obj;
1045                    if (msg.arg1 != 0) {
1046                        if (!app.waitedForDebugger) {
1047                            Dialog d = new AppWaitingForDebuggerDialog(
1048                                    ActivityManagerService.this,
1049                                    mContext, app);
1050                            app.waitDialog = d;
1051                            app.waitedForDebugger = true;
1052                            d.show();
1053                        }
1054                    } else {
1055                        if (app.waitDialog != null) {
1056                            app.waitDialog.dismiss();
1057                            app.waitDialog = null;
1058                        }
1059                    }
1060                }
1061            } break;
1062            case BROADCAST_INTENT_MSG: {
1063                if (DEBUG_BROADCAST) Log.v(
1064                        TAG, "Received BROADCAST_INTENT_MSG");
1065                processNextBroadcast(true);
1066            } break;
1067            case BROADCAST_TIMEOUT_MSG: {
1068                if (mDidDexOpt) {
1069                    mDidDexOpt = false;
1070                    Message nmsg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG);
1071                    mHandler.sendMessageDelayed(nmsg, BROADCAST_TIMEOUT);
1072                    return;
1073                }
1074                broadcastTimeout();
1075            } break;
1076            case PAUSE_TIMEOUT_MSG: {
1077                IBinder token = (IBinder)msg.obj;
1078                // We don't at this point know if the activity is fullscreen,
1079                // so we need to be conservative and assume it isn't.
1080                Log.w(TAG, "Activity pause timeout for " + token);
1081                activityPaused(token, null, true);
1082            } break;
1083            case IDLE_TIMEOUT_MSG: {
1084                if (mDidDexOpt) {
1085                    mDidDexOpt = false;
1086                    Message nmsg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG);
1087                    nmsg.obj = msg.obj;
1088                    mHandler.sendMessageDelayed(nmsg, IDLE_TIMEOUT);
1089                    return;
1090                }
1091                // We don't at this point know if the activity is fullscreen,
1092                // so we need to be conservative and assume it isn't.
1093                IBinder token = (IBinder)msg.obj;
1094                Log.w(TAG, "Activity idle timeout for " + token);
1095                activityIdleInternal(token, true, null);
1096            } break;
1097            case DESTROY_TIMEOUT_MSG: {
1098                IBinder token = (IBinder)msg.obj;
1099                // We don't at this point know if the activity is fullscreen,
1100                // so we need to be conservative and assume it isn't.
1101                Log.w(TAG, "Activity destroy timeout for " + token);
1102                activityDestroyed(token);
1103            } break;
1104            case IDLE_NOW_MSG: {
1105                IBinder token = (IBinder)msg.obj;
1106                activityIdle(token, null);
1107            } break;
1108            case SERVICE_TIMEOUT_MSG: {
1109                if (mDidDexOpt) {
1110                    mDidDexOpt = false;
1111                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1112                    nmsg.obj = msg.obj;
1113                    mHandler.sendMessageDelayed(nmsg, SERVICE_TIMEOUT);
1114                    return;
1115                }
1116                serviceTimeout((ProcessRecord)msg.obj);
1117            } break;
1118            case UPDATE_TIME_ZONE: {
1119                synchronized (ActivityManagerService.this) {
1120                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1121                        ProcessRecord r = mLruProcesses.get(i);
1122                        if (r.thread != null) {
1123                            try {
1124                                r.thread.updateTimeZone();
1125                            } catch (RemoteException ex) {
1126                                Log.w(TAG, "Failed to update time zone for: " + r.info.processName);
1127                            }
1128                        }
1129                    }
1130                }
1131            } break;
1132            case SHOW_UID_ERROR_MSG: {
1133                // XXX This is a temporary dialog, no need to localize.
1134                AlertDialog d = new BaseErrorDialog(mContext);
1135                d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1136                d.setCancelable(false);
1137                d.setTitle("System UIDs Inconsistent");
1138                d.setMessage("UIDs on the system are inconsistent, you need to wipe your data partition or your device will be unstable.");
1139                d.setButton("I'm Feeling Lucky",
1140                        mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1141                mUidAlert = d;
1142                d.show();
1143            } break;
1144            case IM_FEELING_LUCKY_MSG: {
1145                if (mUidAlert != null) {
1146                    mUidAlert.dismiss();
1147                    mUidAlert = null;
1148                }
1149            } break;
1150            case LAUNCH_TIMEOUT_MSG: {
1151                if (mDidDexOpt) {
1152                    mDidDexOpt = false;
1153                    Message nmsg = mHandler.obtainMessage(LAUNCH_TIMEOUT_MSG);
1154                    mHandler.sendMessageDelayed(nmsg, LAUNCH_TIMEOUT);
1155                    return;
1156                }
1157                synchronized (ActivityManagerService.this) {
1158                    if (mLaunchingActivity.isHeld()) {
1159                        Log.w(TAG, "Launch timeout has expired, giving up wake lock!");
1160                        mLaunchingActivity.release();
1161                    }
1162                }
1163            } break;
1164            case SERVICE_ERROR_MSG: {
1165                ServiceRecord srv = (ServiceRecord)msg.obj;
1166                // This needs to be *un*synchronized to avoid deadlock.
1167                Checkin.logEvent(mContext.getContentResolver(),
1168                        Checkin.Events.Tag.SYSTEM_SERVICE_LOOPING,
1169                        srv.name.toShortString());
1170            } break;
1171            case RESUME_TOP_ACTIVITY_MSG: {
1172                synchronized (ActivityManagerService.this) {
1173                    resumeTopActivityLocked(null);
1174                }
1175            } break;
1176            case PROC_START_TIMEOUT_MSG: {
1177                if (mDidDexOpt) {
1178                    mDidDexOpt = false;
1179                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1180                    nmsg.obj = msg.obj;
1181                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1182                    return;
1183                }
1184                ProcessRecord app = (ProcessRecord)msg.obj;
1185                synchronized (ActivityManagerService.this) {
1186                    processStartTimedOutLocked(app);
1187                }
1188            } break;
1189            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1190                synchronized (ActivityManagerService.this) {
1191                    doPendingActivityLaunchesLocked(true);
1192                }
1193            } break;
1194            case KILL_APPLICATION_MSG: {
1195                synchronized (ActivityManagerService.this) {
1196                    int uid = msg.arg1;
1197                    boolean restart = (msg.arg2 == 1);
1198                    String pkg = (String) msg.obj;
1199                    forceStopPackageLocked(pkg, uid, restart, false);
1200                }
1201            } break;
1202            }
1203        }
1204    };
1205
1206    public static void setSystemProcess() {
1207        try {
1208            ActivityManagerService m = mSelf;
1209
1210            ServiceManager.addService("activity", m);
1211            ServiceManager.addService("meminfo", new MemBinder(m));
1212            if (MONITOR_CPU_USAGE) {
1213                ServiceManager.addService("cpuinfo", new CpuBinder(m));
1214            }
1215            ServiceManager.addService("permission", new PermissionController(m));
1216
1217            ApplicationInfo info =
1218                mSelf.mContext.getPackageManager().getApplicationInfo(
1219                        "android", STOCK_PM_FLAGS);
1220            mSystemThread.installSystemApplicationInfo(info);
1221
1222            synchronized (mSelf) {
1223                ProcessRecord app = mSelf.newProcessRecordLocked(
1224                        mSystemThread.getApplicationThread(), info,
1225                        info.processName);
1226                app.persistent = true;
1227                app.pid = MY_PID;
1228                app.maxAdj = SYSTEM_ADJ;
1229                mSelf.mProcessNames.put(app.processName, app.info.uid, app);
1230                synchronized (mSelf.mPidsSelfLocked) {
1231                    mSelf.mPidsSelfLocked.put(app.pid, app);
1232                }
1233                mSelf.updateLruProcessLocked(app, true, true);
1234            }
1235        } catch (PackageManager.NameNotFoundException e) {
1236            throw new RuntimeException(
1237                    "Unable to find android system package", e);
1238        }
1239    }
1240
1241    public void setWindowManager(WindowManagerService wm) {
1242        mWindowManager = wm;
1243    }
1244
1245    public static final Context main(int factoryTest) {
1246        AThread thr = new AThread();
1247        thr.start();
1248
1249        synchronized (thr) {
1250            while (thr.mService == null) {
1251                try {
1252                    thr.wait();
1253                } catch (InterruptedException e) {
1254                }
1255            }
1256        }
1257
1258        ActivityManagerService m = thr.mService;
1259        mSelf = m;
1260        ActivityThread at = ActivityThread.systemMain();
1261        mSystemThread = at;
1262        Context context = at.getSystemContext();
1263        m.mContext = context;
1264        m.mFactoryTest = factoryTest;
1265        PowerManager pm =
1266            (PowerManager)context.getSystemService(Context.POWER_SERVICE);
1267        m.mGoingToSleep = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Sleep");
1268        m.mLaunchingActivity = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Launch");
1269        m.mLaunchingActivity.setReferenceCounted(false);
1270
1271        m.mBatteryStatsService.publish(context);
1272        m.mUsageStatsService.publish(context);
1273
1274        synchronized (thr) {
1275            thr.mReady = true;
1276            thr.notifyAll();
1277        }
1278
1279        m.startRunning(null, null, null, null);
1280
1281        return context;
1282    }
1283
1284    public static ActivityManagerService self() {
1285        return mSelf;
1286    }
1287
1288    static class AThread extends Thread {
1289        ActivityManagerService mService;
1290        boolean mReady = false;
1291
1292        public AThread() {
1293            super("ActivityManager");
1294        }
1295
1296        public void run() {
1297            Looper.prepare();
1298
1299            android.os.Process.setThreadPriority(
1300                    android.os.Process.THREAD_PRIORITY_FOREGROUND);
1301
1302            ActivityManagerService m = new ActivityManagerService();
1303
1304            synchronized (this) {
1305                mService = m;
1306                notifyAll();
1307            }
1308
1309            synchronized (this) {
1310                while (!mReady) {
1311                    try {
1312                        wait();
1313                    } catch (InterruptedException e) {
1314                    }
1315                }
1316            }
1317
1318            Looper.loop();
1319        }
1320    }
1321
1322    static class MemBinder extends Binder {
1323        ActivityManagerService mActivityManagerService;
1324        MemBinder(ActivityManagerService activityManagerService) {
1325            mActivityManagerService = activityManagerService;
1326        }
1327
1328        @Override
1329        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1330            ActivityManagerService service = mActivityManagerService;
1331            ArrayList<ProcessRecord> procs;
1332            synchronized (mActivityManagerService) {
1333                if (args != null && args.length > 0
1334                        && args[0].charAt(0) != '-') {
1335                    procs = new ArrayList<ProcessRecord>();
1336                    int pid = -1;
1337                    try {
1338                        pid = Integer.parseInt(args[0]);
1339                    } catch (NumberFormatException e) {
1340
1341                    }
1342                    for (int i=service.mLruProcesses.size()-1; i>=0; i--) {
1343                        ProcessRecord proc = service.mLruProcesses.get(i);
1344                        if (proc.pid == pid) {
1345                            procs.add(proc);
1346                        } else if (proc.processName.equals(args[0])) {
1347                            procs.add(proc);
1348                        }
1349                    }
1350                    if (procs.size() <= 0) {
1351                        pw.println("No process found for: " + args[0]);
1352                        return;
1353                    }
1354                } else {
1355                    procs = service.mLruProcesses;
1356                }
1357            }
1358            dumpApplicationMemoryUsage(fd, pw, procs, "  ", args);
1359        }
1360    }
1361
1362    static class CpuBinder extends Binder {
1363        ActivityManagerService mActivityManagerService;
1364        CpuBinder(ActivityManagerService activityManagerService) {
1365            mActivityManagerService = activityManagerService;
1366        }
1367
1368        @Override
1369        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1370            synchronized (mActivityManagerService.mProcessStatsThread) {
1371                pw.print(mActivityManagerService.mProcessStats.printCurrentState());
1372            }
1373        }
1374    }
1375
1376    private ActivityManagerService() {
1377        String v = System.getenv("ANDROID_SIMPLE_PROCESS_MANAGEMENT");
1378        if (v != null && Integer.getInteger(v) != 0) {
1379            mSimpleProcessManagement = true;
1380        }
1381        v = System.getenv("ANDROID_DEBUG_APP");
1382        if (v != null) {
1383            mSimpleProcessManagement = true;
1384        }
1385
1386        Log.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
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 ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0) {
1953                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
1954            }
1955            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
1956                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
1957            }
1958            if ("1".equals(SystemProperties.get("debug.assert"))) {
1959                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
1960            }
1961            int pid = Process.start("android.app.ActivityThread",
1962                    mSimpleProcessManagement ? app.processName : null, uid, uid,
1963                    gids, debugFlags, null);
1964            BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
1965            synchronized (bs) {
1966                if (bs.isOnBattery()) {
1967                    app.batteryStats.incStartsLocked();
1968                }
1969            }
1970
1971            EventLog.writeEvent(EventLogTags.AM_PROC_START, pid, uid,
1972                    app.processName, hostingType,
1973                    hostingNameStr != null ? hostingNameStr : "");
1974
1975            if (app.persistent) {
1976                Watchdog.getInstance().processStarted(app, app.processName, pid);
1977            }
1978
1979            StringBuilder buf = mStringBuilder;
1980            buf.setLength(0);
1981            buf.append("Start proc ");
1982            buf.append(app.processName);
1983            buf.append(" for ");
1984            buf.append(hostingType);
1985            if (hostingNameStr != null) {
1986                buf.append(" ");
1987                buf.append(hostingNameStr);
1988            }
1989            buf.append(": pid=");
1990            buf.append(pid);
1991            buf.append(" uid=");
1992            buf.append(uid);
1993            buf.append(" gids={");
1994            if (gids != null) {
1995                for (int gi=0; gi<gids.length; gi++) {
1996                    if (gi != 0) buf.append(", ");
1997                    buf.append(gids[gi]);
1998
1999                }
2000            }
2001            buf.append("}");
2002            Log.i(TAG, buf.toString());
2003            if (pid == 0 || pid == MY_PID) {
2004                // Processes are being emulated with threads.
2005                app.pid = MY_PID;
2006                app.removed = false;
2007                mStartingProcesses.add(app);
2008            } else if (pid > 0) {
2009                app.pid = pid;
2010                app.removed = false;
2011                synchronized (mPidsSelfLocked) {
2012                    this.mPidsSelfLocked.put(pid, app);
2013                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2014                    msg.obj = app;
2015                    mHandler.sendMessageDelayed(msg, PROC_START_TIMEOUT);
2016                }
2017            } else {
2018                app.pid = 0;
2019                RuntimeException e = new RuntimeException(
2020                        "Failure starting process " + app.processName
2021                        + ": returned pid=" + pid);
2022                Log.e(TAG, e.getMessage(), e);
2023            }
2024        } catch (RuntimeException e) {
2025            // XXX do better error recovery.
2026            app.pid = 0;
2027            Log.e(TAG, "Failure starting process " + app.processName, e);
2028        }
2029    }
2030
2031    private final void startPausingLocked(boolean userLeaving, boolean uiSleeping) {
2032        if (mPausingActivity != null) {
2033            RuntimeException e = new RuntimeException();
2034            Log.e(TAG, "Trying to pause when pause is already pending for "
2035                  + mPausingActivity, e);
2036        }
2037        HistoryRecord prev = mResumedActivity;
2038        if (prev == null) {
2039            RuntimeException e = new RuntimeException();
2040            Log.e(TAG, "Trying to pause when nothing is resumed", e);
2041            resumeTopActivityLocked(null);
2042            return;
2043        }
2044        if (DEBUG_PAUSE) Log.v(TAG, "Start pausing: " + prev);
2045        mResumedActivity = null;
2046        mPausingActivity = prev;
2047        mLastPausedActivity = prev;
2048        prev.state = ActivityState.PAUSING;
2049        prev.task.touchActiveTime();
2050
2051        updateCpuStats();
2052
2053        if (prev.app != null && prev.app.thread != null) {
2054            if (DEBUG_PAUSE) Log.v(TAG, "Enqueueing pending pause: " + prev);
2055            try {
2056                EventLog.writeEvent(EventLogTags.AM_PAUSE_ACTIVITY,
2057                        System.identityHashCode(prev),
2058                        prev.shortComponentName);
2059                prev.app.thread.schedulePauseActivity(prev, prev.finishing, userLeaving,
2060                        prev.configChangeFlags);
2061                updateUsageStats(prev, false);
2062            } catch (Exception e) {
2063                // Ignore exception, if process died other code will cleanup.
2064                Log.w(TAG, "Exception thrown during pause", e);
2065                mPausingActivity = null;
2066                mLastPausedActivity = null;
2067            }
2068        } else {
2069            mPausingActivity = null;
2070            mLastPausedActivity = null;
2071        }
2072
2073        // If we are not going to sleep, we want to ensure the device is
2074        // awake until the next activity is started.
2075        if (!mSleeping && !mShuttingDown) {
2076            mLaunchingActivity.acquire();
2077            if (!mHandler.hasMessages(LAUNCH_TIMEOUT_MSG)) {
2078                // To be safe, don't allow the wake lock to be held for too long.
2079                Message msg = mHandler.obtainMessage(LAUNCH_TIMEOUT_MSG);
2080                mHandler.sendMessageDelayed(msg, LAUNCH_TIMEOUT);
2081            }
2082        }
2083
2084
2085        if (mPausingActivity != null) {
2086            // Have the window manager pause its key dispatching until the new
2087            // activity has started.  If we're pausing the activity just because
2088            // the screen is being turned off and the UI is sleeping, don't interrupt
2089            // key dispatch; the same activity will pick it up again on wakeup.
2090            if (!uiSleeping) {
2091                prev.pauseKeyDispatchingLocked();
2092            } else {
2093                if (DEBUG_PAUSE) Log.v(TAG, "Key dispatch not paused for screen off");
2094            }
2095
2096            // Schedule a pause timeout in case the app doesn't respond.
2097            // We don't give it much time because this directly impacts the
2098            // responsiveness seen by the user.
2099            Message msg = mHandler.obtainMessage(PAUSE_TIMEOUT_MSG);
2100            msg.obj = prev;
2101            mHandler.sendMessageDelayed(msg, PAUSE_TIMEOUT);
2102            if (DEBUG_PAUSE) Log.v(TAG, "Waiting for pause to complete...");
2103        } else {
2104            // This activity failed to schedule the
2105            // pause, so just treat it as being paused now.
2106            if (DEBUG_PAUSE) Log.v(TAG, "Activity not running, resuming next.");
2107            resumeTopActivityLocked(null);
2108        }
2109    }
2110
2111    private final void completePauseLocked() {
2112        HistoryRecord prev = mPausingActivity;
2113        if (DEBUG_PAUSE) Log.v(TAG, "Complete pause: " + prev);
2114
2115        if (prev != null) {
2116            if (prev.finishing) {
2117                if (DEBUG_PAUSE) Log.v(TAG, "Executing finish of activity: " + prev);
2118                prev = finishCurrentActivityLocked(prev, FINISH_AFTER_VISIBLE);
2119            } else if (prev.app != null) {
2120                if (DEBUG_PAUSE) Log.v(TAG, "Enqueueing pending stop: " + prev);
2121                if (prev.waitingVisible) {
2122                    prev.waitingVisible = false;
2123                    mWaitingVisibleActivities.remove(prev);
2124                    if (DEBUG_SWITCH || DEBUG_PAUSE) Log.v(
2125                            TAG, "Complete pause, no longer waiting: " + prev);
2126                }
2127                if (prev.configDestroy) {
2128                    // The previous is being paused because the configuration
2129                    // is changing, which means it is actually stopping...
2130                    // To juggle the fact that we are also starting a new
2131                    // instance right now, we need to first completely stop
2132                    // the current instance before starting the new one.
2133                    if (DEBUG_PAUSE) Log.v(TAG, "Destroying after pause: " + prev);
2134                    destroyActivityLocked(prev, true);
2135                } else {
2136                    mStoppingActivities.add(prev);
2137                    if (mStoppingActivities.size() > 3) {
2138                        // If we already have a few activities waiting to stop,
2139                        // then give up on things going idle and start clearing
2140                        // them out.
2141                        if (DEBUG_PAUSE) Log.v(TAG, "To many pending stops, forcing idle");
2142                        Message msg = Message.obtain();
2143                        msg.what = ActivityManagerService.IDLE_NOW_MSG;
2144                        mHandler.sendMessage(msg);
2145                    }
2146                }
2147            } else {
2148                if (DEBUG_PAUSE) Log.v(TAG, "App died during pause, not stopping: " + prev);
2149                prev = null;
2150            }
2151            mPausingActivity = null;
2152        }
2153
2154        if (!mSleeping && !mShuttingDown) {
2155            resumeTopActivityLocked(prev);
2156        } else {
2157            if (mGoingToSleep.isHeld()) {
2158                mGoingToSleep.release();
2159            }
2160            if (mShuttingDown) {
2161                notifyAll();
2162            }
2163        }
2164
2165        if (prev != null) {
2166            prev.resumeKeyDispatchingLocked();
2167        }
2168
2169        if (prev.app != null && prev.cpuTimeAtResume > 0 && mBatteryStatsService.isOnBattery()) {
2170            long diff = 0;
2171            synchronized (mProcessStatsThread) {
2172                diff = mProcessStats.getCpuTimeForPid(prev.app.pid) - prev.cpuTimeAtResume;
2173            }
2174            if (diff > 0) {
2175                BatteryStatsImpl bsi = mBatteryStatsService.getActiveStatistics();
2176                synchronized (bsi) {
2177                    BatteryStatsImpl.Uid.Proc ps =
2178                            bsi.getProcessStatsLocked(prev.info.applicationInfo.uid,
2179                            prev.info.packageName);
2180                    if (ps != null) {
2181                        ps.addForegroundTimeLocked(diff);
2182                    }
2183                }
2184            }
2185        }
2186        prev.cpuTimeAtResume = 0; // reset it
2187    }
2188
2189    /**
2190     * Once we know that we have asked an application to put an activity in
2191     * the resumed state (either by launching it or explicitly telling it),
2192     * this function updates the rest of our state to match that fact.
2193     */
2194    private final void completeResumeLocked(HistoryRecord next) {
2195        next.idle = false;
2196        next.results = null;
2197        next.newIntents = null;
2198
2199        // schedule an idle timeout in case the app doesn't do it for us.
2200        Message msg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG);
2201        msg.obj = next;
2202        mHandler.sendMessageDelayed(msg, IDLE_TIMEOUT);
2203
2204        if (false) {
2205            // The activity was never told to pause, so just keep
2206            // things going as-is.  To maintain our own state,
2207            // we need to emulate it coming back and saying it is
2208            // idle.
2209            msg = mHandler.obtainMessage(IDLE_NOW_MSG);
2210            msg.obj = next;
2211            mHandler.sendMessage(msg);
2212        }
2213
2214        reportResumedActivityLocked(next);
2215
2216        next.thumbnail = null;
2217        setFocusedActivityLocked(next);
2218        next.resumeKeyDispatchingLocked();
2219        ensureActivitiesVisibleLocked(null, 0);
2220        mWindowManager.executeAppTransition();
2221        mNoAnimActivities.clear();
2222
2223        // Mark the point when the activity is resuming
2224        // TODO: To be more accurate, the mark should be before the onCreate,
2225        //       not after the onResume. But for subsequent starts, onResume is fine.
2226        if (next.app != null) {
2227            synchronized (mProcessStatsThread) {
2228                next.cpuTimeAtResume = mProcessStats.getCpuTimeForPid(next.app.pid);
2229            }
2230        } else {
2231            next.cpuTimeAtResume = 0; // Couldn't get the cpu time of process
2232        }
2233    }
2234
2235    /**
2236     * Make sure that all activities that need to be visible (that is, they
2237     * currently can be seen by the user) actually are.
2238     */
2239    private final void ensureActivitiesVisibleLocked(HistoryRecord top,
2240            HistoryRecord starting, String onlyThisProcess, int configChanges) {
2241        if (DEBUG_VISBILITY) Log.v(
2242                TAG, "ensureActivitiesVisible behind " + top
2243                + " configChanges=0x" + Integer.toHexString(configChanges));
2244
2245        // If the top activity is not fullscreen, then we need to
2246        // make sure any activities under it are now visible.
2247        final int count = mHistory.size();
2248        int i = count-1;
2249        while (mHistory.get(i) != top) {
2250            i--;
2251        }
2252        HistoryRecord r;
2253        boolean behindFullscreen = false;
2254        for (; i>=0; i--) {
2255            r = (HistoryRecord)mHistory.get(i);
2256            if (DEBUG_VISBILITY) Log.v(
2257                    TAG, "Make visible? " + r + " finishing=" + r.finishing
2258                    + " state=" + r.state);
2259            if (r.finishing) {
2260                continue;
2261            }
2262
2263            final boolean doThisProcess = onlyThisProcess == null
2264                    || onlyThisProcess.equals(r.processName);
2265
2266            // First: if this is not the current activity being started, make
2267            // sure it matches the current configuration.
2268            if (r != starting && doThisProcess) {
2269                ensureActivityConfigurationLocked(r, 0);
2270            }
2271
2272            if (r.app == null || r.app.thread == null) {
2273                if (onlyThisProcess == null
2274                        || onlyThisProcess.equals(r.processName)) {
2275                    // This activity needs to be visible, but isn't even
2276                    // running...  get it started, but don't resume it
2277                    // at this point.
2278                    if (DEBUG_VISBILITY) Log.v(
2279                            TAG, "Start and freeze screen for " + r);
2280                    if (r != starting) {
2281                        r.startFreezingScreenLocked(r.app, configChanges);
2282                    }
2283                    if (!r.visible) {
2284                        if (DEBUG_VISBILITY) Log.v(
2285                                TAG, "Starting and making visible: " + r);
2286                        mWindowManager.setAppVisibility(r, true);
2287                    }
2288                    if (r != starting) {
2289                        startSpecificActivityLocked(r, false, false);
2290                    }
2291                }
2292
2293            } else if (r.visible) {
2294                // If this activity is already visible, then there is nothing
2295                // else to do here.
2296                if (DEBUG_VISBILITY) Log.v(
2297                        TAG, "Skipping: already visible at " + r);
2298                r.stopFreezingScreenLocked(false);
2299
2300            } else if (onlyThisProcess == null) {
2301                // This activity is not currently visible, but is running.
2302                // Tell it to become visible.
2303                r.visible = true;
2304                if (r.state != ActivityState.RESUMED && r != starting) {
2305                    // If this activity is paused, tell it
2306                    // to now show its window.
2307                    if (DEBUG_VISBILITY) Log.v(
2308                            TAG, "Making visible and scheduling visibility: " + r);
2309                    try {
2310                        mWindowManager.setAppVisibility(r, true);
2311                        r.app.thread.scheduleWindowVisibility(r, true);
2312                        r.stopFreezingScreenLocked(false);
2313                    } catch (Exception e) {
2314                        // Just skip on any failure; we'll make it
2315                        // visible when it next restarts.
2316                        Log.w(TAG, "Exception thrown making visibile: "
2317                                + r.intent.getComponent(), e);
2318                    }
2319                }
2320            }
2321
2322            // Aggregate current change flags.
2323            configChanges |= r.configChangeFlags;
2324
2325            if (r.fullscreen) {
2326                // At this point, nothing else needs to be shown
2327                if (DEBUG_VISBILITY) Log.v(
2328                        TAG, "Stopping: fullscreen at " + r);
2329                behindFullscreen = true;
2330                i--;
2331                break;
2332            }
2333        }
2334
2335        // Now for any activities that aren't visible to the user, make
2336        // sure they no longer are keeping the screen frozen.
2337        while (i >= 0) {
2338            r = (HistoryRecord)mHistory.get(i);
2339            if (DEBUG_VISBILITY) Log.v(
2340                    TAG, "Make invisible? " + r + " finishing=" + r.finishing
2341                    + " state=" + r.state
2342                    + " behindFullscreen=" + behindFullscreen);
2343            if (!r.finishing) {
2344                if (behindFullscreen) {
2345                    if (r.visible) {
2346                        if (DEBUG_VISBILITY) Log.v(
2347                                TAG, "Making invisible: " + r);
2348                        r.visible = false;
2349                        try {
2350                            mWindowManager.setAppVisibility(r, false);
2351                            if ((r.state == ActivityState.STOPPING
2352                                    || r.state == ActivityState.STOPPED)
2353                                    && r.app != null && r.app.thread != null) {
2354                                if (DEBUG_VISBILITY) Log.v(
2355                                        TAG, "Scheduling invisibility: " + r);
2356                                r.app.thread.scheduleWindowVisibility(r, false);
2357                            }
2358                        } catch (Exception e) {
2359                            // Just skip on any failure; we'll make it
2360                            // visible when it next restarts.
2361                            Log.w(TAG, "Exception thrown making hidden: "
2362                                    + r.intent.getComponent(), e);
2363                        }
2364                    } else {
2365                        if (DEBUG_VISBILITY) Log.v(
2366                                TAG, "Already invisible: " + r);
2367                    }
2368                } else if (r.fullscreen) {
2369                    if (DEBUG_VISBILITY) Log.v(
2370                            TAG, "Now behindFullscreen: " + r);
2371                    behindFullscreen = true;
2372                }
2373            }
2374            i--;
2375        }
2376    }
2377
2378    /**
2379     * Version of ensureActivitiesVisible that can easily be called anywhere.
2380     */
2381    private final void ensureActivitiesVisibleLocked(HistoryRecord starting,
2382            int configChanges) {
2383        HistoryRecord r = topRunningActivityLocked(null);
2384        if (r != null) {
2385            ensureActivitiesVisibleLocked(r, starting, null, configChanges);
2386        }
2387    }
2388
2389    private void updateUsageStats(HistoryRecord resumedComponent, boolean resumed) {
2390        if (resumed) {
2391            mUsageStatsService.noteResumeComponent(resumedComponent.realActivity);
2392        } else {
2393            mUsageStatsService.notePauseComponent(resumedComponent.realActivity);
2394        }
2395    }
2396
2397    private boolean startHomeActivityLocked() {
2398        if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2399                && mTopAction == null) {
2400            // We are running in factory test mode, but unable to find
2401            // the factory test app, so just sit around displaying the
2402            // error message and don't try to start anything.
2403            return false;
2404        }
2405        Intent intent = new Intent(
2406            mTopAction,
2407            mTopData != null ? Uri.parse(mTopData) : null);
2408        intent.setComponent(mTopComponent);
2409        if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
2410            intent.addCategory(Intent.CATEGORY_HOME);
2411        }
2412        ActivityInfo aInfo =
2413            intent.resolveActivityInfo(mContext.getPackageManager(),
2414                    STOCK_PM_FLAGS);
2415        if (aInfo != null) {
2416            intent.setComponent(new ComponentName(
2417                    aInfo.applicationInfo.packageName, aInfo.name));
2418            // Don't do this if the home app is currently being
2419            // instrumented.
2420            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2421                    aInfo.applicationInfo.uid);
2422            if (app == null || app.instrumentationClass == null) {
2423                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
2424                startActivityLocked(null, intent, null, null, 0, aInfo,
2425                        null, null, 0, 0, 0, false, false);
2426            }
2427        }
2428
2429
2430        return true;
2431    }
2432
2433    /**
2434     * Starts the "new version setup screen" if appropriate.
2435     */
2436    private void startSetupActivityLocked() {
2437        // Only do this once per boot.
2438        if (mCheckedForSetup) {
2439            return;
2440        }
2441
2442        // We will show this screen if the current one is a different
2443        // version than the last one shown, and we are not running in
2444        // low-level factory test mode.
2445        final ContentResolver resolver = mContext.getContentResolver();
2446        if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL &&
2447                Settings.Secure.getInt(resolver,
2448                        Settings.Secure.DEVICE_PROVISIONED, 0) != 0) {
2449            mCheckedForSetup = true;
2450
2451            // See if we should be showing the platform update setup UI.
2452            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
2453            List<ResolveInfo> ris = mSelf.mContext.getPackageManager()
2454                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
2455
2456            // We don't allow third party apps to replace this.
2457            ResolveInfo ri = null;
2458            for (int i=0; ris != null && i<ris.size(); i++) {
2459                if ((ris.get(i).activityInfo.applicationInfo.flags
2460                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
2461                    ri = ris.get(i);
2462                    break;
2463                }
2464            }
2465
2466            if (ri != null) {
2467                String vers = ri.activityInfo.metaData != null
2468                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2469                        : null;
2470                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2471                    vers = ri.activityInfo.applicationInfo.metaData.getString(
2472                            Intent.METADATA_SETUP_VERSION);
2473                }
2474                String lastVers = Settings.Secure.getString(
2475                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
2476                if (vers != null && !vers.equals(lastVers)) {
2477                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2478                    intent.setComponent(new ComponentName(
2479                            ri.activityInfo.packageName, ri.activityInfo.name));
2480                    startActivityLocked(null, intent, null, null, 0, ri.activityInfo,
2481                            null, null, 0, 0, 0, false, false);
2482                }
2483            }
2484        }
2485    }
2486
2487    private void reportResumedActivityLocked(HistoryRecord r) {
2488        //Log.i(TAG, "**** REPORT RESUME: " + r);
2489
2490        final int identHash = System.identityHashCode(r);
2491        updateUsageStats(r, true);
2492
2493        int i = mWatchers.beginBroadcast();
2494        while (i > 0) {
2495            i--;
2496            IActivityWatcher w = mWatchers.getBroadcastItem(i);
2497            if (w != null) {
2498                try {
2499                    w.activityResuming(identHash);
2500                } catch (RemoteException e) {
2501                }
2502            }
2503        }
2504        mWatchers.finishBroadcast();
2505    }
2506
2507    /**
2508     * Ensure that the top activity in the stack is resumed.
2509     *
2510     * @param prev The previously resumed activity, for when in the process
2511     * of pausing; can be null to call from elsewhere.
2512     *
2513     * @return Returns true if something is being resumed, or false if
2514     * nothing happened.
2515     */
2516    private final boolean resumeTopActivityLocked(HistoryRecord prev) {
2517        // Find the first activity that is not finishing.
2518        HistoryRecord next = topRunningActivityLocked(null);
2519
2520        // Remember how we'll process this pause/resume situation, and ensure
2521        // that the state is reset however we wind up proceeding.
2522        final boolean userLeaving = mUserLeaving;
2523        mUserLeaving = false;
2524
2525        if (next == null) {
2526            // There are no more activities!  Let's just start up the
2527            // Launcher...
2528            return startHomeActivityLocked();
2529        }
2530
2531        next.delayedResume = false;
2532
2533        // If the top activity is the resumed one, nothing to do.
2534        if (mResumedActivity == next && next.state == ActivityState.RESUMED) {
2535            // Make sure we have executed any pending transitions, since there
2536            // should be nothing left to do at this point.
2537            mWindowManager.executeAppTransition();
2538            mNoAnimActivities.clear();
2539            return false;
2540        }
2541
2542        // If we are sleeping, and there is no resumed activity, and the top
2543        // activity is paused, well that is the state we want.
2544        if ((mSleeping || mShuttingDown)
2545                && mLastPausedActivity == next && next.state == ActivityState.PAUSED) {
2546            // Make sure we have executed any pending transitions, since there
2547            // should be nothing left to do at this point.
2548            mWindowManager.executeAppTransition();
2549            mNoAnimActivities.clear();
2550            return false;
2551        }
2552
2553        // The activity may be waiting for stop, but that is no longer
2554        // appropriate for it.
2555        mStoppingActivities.remove(next);
2556        mWaitingVisibleActivities.remove(next);
2557
2558        if (DEBUG_SWITCH) Log.v(TAG, "Resuming " + next);
2559
2560        // If we are currently pausing an activity, then don't do anything
2561        // until that is done.
2562        if (mPausingActivity != null) {
2563            if (DEBUG_SWITCH) Log.v(TAG, "Skip resume: pausing=" + mPausingActivity);
2564            return false;
2565        }
2566
2567        // We need to start pausing the current activity so the top one
2568        // can be resumed...
2569        if (mResumedActivity != null) {
2570            if (DEBUG_SWITCH) Log.v(TAG, "Skip resume: need to start pausing");
2571            startPausingLocked(userLeaving, false);
2572            return true;
2573        }
2574
2575        if (prev != null && prev != next) {
2576            if (!prev.waitingVisible && next != null && !next.nowVisible) {
2577                prev.waitingVisible = true;
2578                mWaitingVisibleActivities.add(prev);
2579                if (DEBUG_SWITCH) Log.v(
2580                        TAG, "Resuming top, waiting visible to hide: " + prev);
2581            } else {
2582                // The next activity is already visible, so hide the previous
2583                // activity's windows right now so we can show the new one ASAP.
2584                // We only do this if the previous is finishing, which should mean
2585                // it is on top of the one being resumed so hiding it quickly
2586                // is good.  Otherwise, we want to do the normal route of allowing
2587                // the resumed activity to be shown so we can decide if the
2588                // previous should actually be hidden depending on whether the
2589                // new one is found to be full-screen or not.
2590                if (prev.finishing) {
2591                    mWindowManager.setAppVisibility(prev, false);
2592                    if (DEBUG_SWITCH) Log.v(TAG, "Not waiting for visible to hide: "
2593                            + prev + ", waitingVisible="
2594                            + (prev != null ? prev.waitingVisible : null)
2595                            + ", nowVisible=" + next.nowVisible);
2596                } else {
2597                    if (DEBUG_SWITCH) Log.v(TAG, "Previous already visible but still waiting to hide: "
2598                        + prev + ", waitingVisible="
2599                        + (prev != null ? prev.waitingVisible : null)
2600                        + ", nowVisible=" + next.nowVisible);
2601                }
2602            }
2603        }
2604
2605        // We are starting up the next activity, so tell the window manager
2606        // that the previous one will be hidden soon.  This way it can know
2607        // to ignore it when computing the desired screen orientation.
2608        if (prev != null) {
2609            if (prev.finishing) {
2610                if (DEBUG_TRANSITION) Log.v(TAG,
2611                        "Prepare close transition: prev=" + prev);
2612                if (mNoAnimActivities.contains(prev)) {
2613                    mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_NONE);
2614                } else {
2615                    mWindowManager.prepareAppTransition(prev.task == next.task
2616                            ? WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE
2617                            : WindowManagerPolicy.TRANSIT_TASK_CLOSE);
2618                }
2619                mWindowManager.setAppWillBeHidden(prev);
2620                mWindowManager.setAppVisibility(prev, false);
2621            } else {
2622                if (DEBUG_TRANSITION) Log.v(TAG,
2623                        "Prepare open transition: prev=" + prev);
2624                if (mNoAnimActivities.contains(next)) {
2625                    mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_NONE);
2626                } else {
2627                    mWindowManager.prepareAppTransition(prev.task == next.task
2628                            ? WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
2629                            : WindowManagerPolicy.TRANSIT_TASK_OPEN);
2630                }
2631            }
2632            if (false) {
2633                mWindowManager.setAppWillBeHidden(prev);
2634                mWindowManager.setAppVisibility(prev, false);
2635            }
2636        } else if (mHistory.size() > 1) {
2637            if (DEBUG_TRANSITION) Log.v(TAG,
2638                    "Prepare open transition: no previous");
2639            if (mNoAnimActivities.contains(next)) {
2640                mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_NONE);
2641            } else {
2642                mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN);
2643            }
2644        }
2645
2646        if (next.app != null && next.app.thread != null) {
2647            if (DEBUG_SWITCH) Log.v(TAG, "Resume running: " + next);
2648
2649            // This activity is now becoming visible.
2650            mWindowManager.setAppVisibility(next, true);
2651
2652            HistoryRecord lastResumedActivity = mResumedActivity;
2653            ActivityState lastState = next.state;
2654
2655            updateCpuStats();
2656
2657            next.state = ActivityState.RESUMED;
2658            mResumedActivity = next;
2659            next.task.touchActiveTime();
2660            updateLruProcessLocked(next.app, true, true);
2661            updateLRUListLocked(next);
2662
2663            // Have the window manager re-evaluate the orientation of
2664            // the screen based on the new activity order.
2665            boolean updated;
2666            synchronized (this) {
2667                Configuration config = mWindowManager.updateOrientationFromAppTokens(
2668                        mConfiguration,
2669                        next.mayFreezeScreenLocked(next.app) ? next : null);
2670                if (config != null) {
2671                    /*
2672                     * Explicitly restore the locale to the one from the
2673                     * old configuration, since the one that comes back from
2674                     * the window manager has the default (boot) locale.
2675                     *
2676                     * It looks like previously the locale picker only worked
2677                     * by coincidence: usually it would do its setting of
2678                     * the locale after the activity transition, so it didn't
2679                     * matter that this lost it.  With the synchronized
2680                     * block now keeping them from happening at the same time,
2681                     * this one always would happen second and undo what the
2682                     * locale picker had just done.
2683                     */
2684                    config.locale = mConfiguration.locale;
2685                    next.frozenBeforeDestroy = true;
2686                }
2687                updated = updateConfigurationLocked(config, next);
2688            }
2689            if (!updated) {
2690                // The configuration update wasn't able to keep the existing
2691                // instance of the activity, and instead started a new one.
2692                // We should be all done, but let's just make sure our activity
2693                // is still at the top and schedule another run if something
2694                // weird happened.
2695                HistoryRecord nextNext = topRunningActivityLocked(null);
2696                if (DEBUG_SWITCH) Log.i(TAG,
2697                        "Activity config changed during resume: " + next
2698                        + ", new next: " + nextNext);
2699                if (nextNext != next) {
2700                    // Do over!
2701                    mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG);
2702                }
2703                setFocusedActivityLocked(next);
2704                ensureActivitiesVisibleLocked(null, 0);
2705                mWindowManager.executeAppTransition();
2706                mNoAnimActivities.clear();
2707                return true;
2708            }
2709
2710            try {
2711                // Deliver all pending results.
2712                ArrayList a = next.results;
2713                if (a != null) {
2714                    final int N = a.size();
2715                    if (!next.finishing && N > 0) {
2716                        if (DEBUG_RESULTS) Log.v(
2717                                TAG, "Delivering results to " + next
2718                                + ": " + a);
2719                        next.app.thread.scheduleSendResult(next, a);
2720                    }
2721                }
2722
2723                if (next.newIntents != null) {
2724                    next.app.thread.scheduleNewIntent(next.newIntents, next);
2725                }
2726
2727                EventLog.writeEvent(EventLogTags.AM_RESUME_ACTIVITY,
2728                        System.identityHashCode(next),
2729                        next.task.taskId, next.shortComponentName);
2730
2731                next.app.thread.scheduleResumeActivity(next,
2732                        isNextTransitionForward());
2733
2734                pauseIfSleepingLocked();
2735
2736            } catch (Exception e) {
2737                // Whoops, need to restart this activity!
2738                next.state = lastState;
2739                mResumedActivity = lastResumedActivity;
2740                Log.i(TAG, "Restarting because process died: " + next);
2741                if (!next.hasBeenLaunched) {
2742                    next.hasBeenLaunched = true;
2743                } else {
2744                    if (SHOW_APP_STARTING_ICON) {
2745                        mWindowManager.setAppStartingWindow(
2746                                next, next.packageName, next.theme,
2747                                next.nonLocalizedLabel,
2748                                next.labelRes, next.icon, null, true);
2749                    }
2750                }
2751                startSpecificActivityLocked(next, true, false);
2752                return true;
2753            }
2754
2755            // From this point on, if something goes wrong there is no way
2756            // to recover the activity.
2757            try {
2758                next.visible = true;
2759                completeResumeLocked(next);
2760            } catch (Exception e) {
2761                // If any exception gets thrown, toss away this
2762                // activity and try the next one.
2763                Log.w(TAG, "Exception thrown during resume of " + next, e);
2764                requestFinishActivityLocked(next, Activity.RESULT_CANCELED, null,
2765                        "resume-exception");
2766                return true;
2767            }
2768
2769            // Didn't need to use the icicle, and it is now out of date.
2770            next.icicle = null;
2771            next.haveState = false;
2772            next.stopped = false;
2773
2774        } else {
2775            // Whoops, need to restart this activity!
2776            if (!next.hasBeenLaunched) {
2777                next.hasBeenLaunched = true;
2778            } else {
2779                if (SHOW_APP_STARTING_ICON) {
2780                    mWindowManager.setAppStartingWindow(
2781                            next, next.packageName, next.theme,
2782                            next.nonLocalizedLabel,
2783                            next.labelRes, next.icon, null, true);
2784                }
2785                if (DEBUG_SWITCH) Log.v(TAG, "Restarting: " + next);
2786            }
2787            startSpecificActivityLocked(next, true, true);
2788        }
2789
2790        return true;
2791    }
2792
2793    private final void startActivityLocked(HistoryRecord r, boolean newTask,
2794            boolean doResume) {
2795        final int NH = mHistory.size();
2796
2797        int addPos = -1;
2798
2799        if (!newTask) {
2800            // If starting in an existing task, find where that is...
2801            HistoryRecord next = null;
2802            boolean startIt = true;
2803            for (int i = NH-1; i >= 0; i--) {
2804                HistoryRecord p = (HistoryRecord)mHistory.get(i);
2805                if (p.finishing) {
2806                    continue;
2807                }
2808                if (p.task == r.task) {
2809                    // Here it is!  Now, if this is not yet visible to the
2810                    // user, then just add it without starting; it will
2811                    // get started when the user navigates back to it.
2812                    addPos = i+1;
2813                    if (!startIt) {
2814                        mHistory.add(addPos, r);
2815                        r.inHistory = true;
2816                        r.task.numActivities++;
2817                        mWindowManager.addAppToken(addPos, r, r.task.taskId,
2818                                r.info.screenOrientation, r.fullscreen);
2819                        if (VALIDATE_TOKENS) {
2820                            mWindowManager.validateAppTokens(mHistory);
2821                        }
2822                        return;
2823                    }
2824                    break;
2825                }
2826                if (p.fullscreen) {
2827                    startIt = false;
2828                }
2829                next = p;
2830            }
2831        }
2832
2833        // Place a new activity at top of stack, so it is next to interact
2834        // with the user.
2835        if (addPos < 0) {
2836            addPos = mHistory.size();
2837        }
2838
2839        // If we are not placing the new activity frontmost, we do not want
2840        // to deliver the onUserLeaving callback to the actual frontmost
2841        // activity
2842        if (addPos < NH) {
2843            mUserLeaving = false;
2844            if (DEBUG_USER_LEAVING) Log.v(TAG, "startActivity() behind front, mUserLeaving=false");
2845        }
2846
2847        // Slot the activity into the history stack and proceed
2848        mHistory.add(addPos, r);
2849        r.inHistory = true;
2850        r.frontOfTask = newTask;
2851        r.task.numActivities++;
2852        if (NH > 0) {
2853            // We want to show the starting preview window if we are
2854            // switching to a new task, or the next activity's process is
2855            // not currently running.
2856            boolean showStartingIcon = newTask;
2857            ProcessRecord proc = r.app;
2858            if (proc == null) {
2859                proc = mProcessNames.get(r.processName, r.info.applicationInfo.uid);
2860            }
2861            if (proc == null || proc.thread == null) {
2862                showStartingIcon = true;
2863            }
2864            if (DEBUG_TRANSITION) Log.v(TAG,
2865                    "Prepare open transition: starting " + r);
2866            if ((r.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) {
2867                mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_NONE);
2868                mNoAnimActivities.add(r);
2869            } else if ((r.intent.getFlags()&Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0) {
2870                mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_TASK_OPEN);
2871                mNoAnimActivities.remove(r);
2872            } else {
2873                mWindowManager.prepareAppTransition(newTask
2874                        ? WindowManagerPolicy.TRANSIT_TASK_OPEN
2875                        : WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN);
2876                mNoAnimActivities.remove(r);
2877            }
2878            mWindowManager.addAppToken(
2879                    addPos, r, r.task.taskId, r.info.screenOrientation, r.fullscreen);
2880            boolean doShow = true;
2881            if (newTask) {
2882                // Even though this activity is starting fresh, we still need
2883                // to reset it to make sure we apply affinities to move any
2884                // existing activities from other tasks in to it.
2885                // If the caller has requested that the target task be
2886                // reset, then do so.
2887                if ((r.intent.getFlags()
2888                        &Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
2889                    resetTaskIfNeededLocked(r, r);
2890                    doShow = topRunningNonDelayedActivityLocked(null) == r;
2891                }
2892            }
2893            if (SHOW_APP_STARTING_ICON && doShow) {
2894                // Figure out if we are transitioning from another activity that is
2895                // "has the same starting icon" as the next one.  This allows the
2896                // window manager to keep the previous window it had previously
2897                // created, if it still had one.
2898                HistoryRecord prev = mResumedActivity;
2899                if (prev != null) {
2900                    // We don't want to reuse the previous starting preview if:
2901                    // (1) The current activity is in a different task.
2902                    if (prev.task != r.task) prev = null;
2903                    // (2) The current activity is already displayed.
2904                    else if (prev.nowVisible) prev = null;
2905                }
2906                mWindowManager.setAppStartingWindow(
2907                        r, r.packageName, r.theme, r.nonLocalizedLabel,
2908                        r.labelRes, r.icon, prev, showStartingIcon);
2909            }
2910        } else {
2911            // If this is the first activity, don't do any fancy animations,
2912            // because there is nothing for it to animate on top of.
2913            mWindowManager.addAppToken(addPos, r, r.task.taskId,
2914                    r.info.screenOrientation, r.fullscreen);
2915        }
2916        if (VALIDATE_TOKENS) {
2917            mWindowManager.validateAppTokens(mHistory);
2918        }
2919
2920        if (doResume) {
2921            resumeTopActivityLocked(null);
2922        }
2923    }
2924
2925    /**
2926     * Perform clear operation as requested by
2927     * {@link Intent#FLAG_ACTIVITY_CLEAR_TOP}: search from the top of the
2928     * stack to the given task, then look for
2929     * an instance of that activity in the stack and, if found, finish all
2930     * activities on top of it and return the instance.
2931     *
2932     * @param newR Description of the new activity being started.
2933     * @return Returns the old activity that should be continue to be used,
2934     * or null if none was found.
2935     */
2936    private final HistoryRecord performClearTaskLocked(int taskId,
2937            HistoryRecord newR, int launchFlags, boolean doClear) {
2938        int i = mHistory.size();
2939
2940        // First find the requested task.
2941        while (i > 0) {
2942            i--;
2943            HistoryRecord r = (HistoryRecord)mHistory.get(i);
2944            if (r.task.taskId == taskId) {
2945                i++;
2946                break;
2947            }
2948        }
2949
2950        // Now clear it.
2951        while (i > 0) {
2952            i--;
2953            HistoryRecord r = (HistoryRecord)mHistory.get(i);
2954            if (r.finishing) {
2955                continue;
2956            }
2957            if (r.task.taskId != taskId) {
2958                return null;
2959            }
2960            if (r.realActivity.equals(newR.realActivity)) {
2961                // Here it is!  Now finish everything in front...
2962                HistoryRecord ret = r;
2963                if (doClear) {
2964                    while (i < (mHistory.size()-1)) {
2965                        i++;
2966                        r = (HistoryRecord)mHistory.get(i);
2967                        if (r.finishing) {
2968                            continue;
2969                        }
2970                        if (finishActivityLocked(r, i, Activity.RESULT_CANCELED,
2971                                null, "clear")) {
2972                            i--;
2973                        }
2974                    }
2975                }
2976
2977                // Finally, if this is a normal launch mode (that is, not
2978                // expecting onNewIntent()), then we will finish the current
2979                // instance of the activity so a new fresh one can be started.
2980                if (ret.launchMode == ActivityInfo.LAUNCH_MULTIPLE
2981                        && (launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) == 0) {
2982                    if (!ret.finishing) {
2983                        int index = indexOfTokenLocked(ret);
2984                        if (index >= 0) {
2985                            finishActivityLocked(ret, 0, Activity.RESULT_CANCELED,
2986                                    null, "clear");
2987                        }
2988                        return null;
2989                    }
2990                }
2991
2992                return ret;
2993            }
2994        }
2995
2996        return null;
2997    }
2998
2999    /**
3000     * Find the activity in the history stack within the given task.  Returns
3001     * the index within the history at which it's found, or < 0 if not found.
3002     */
3003    private final int findActivityInHistoryLocked(HistoryRecord r, int task) {
3004        int i = mHistory.size();
3005        while (i > 0) {
3006            i--;
3007            HistoryRecord candidate = (HistoryRecord)mHistory.get(i);
3008            if (candidate.task.taskId != task) {
3009                break;
3010            }
3011            if (candidate.realActivity.equals(r.realActivity)) {
3012                return i;
3013            }
3014        }
3015
3016        return -1;
3017    }
3018
3019    /**
3020     * Reorder the history stack so that the activity at the given index is
3021     * brought to the front.
3022     */
3023    private final HistoryRecord moveActivityToFrontLocked(int where) {
3024        HistoryRecord newTop = (HistoryRecord)mHistory.remove(where);
3025        int top = mHistory.size();
3026        HistoryRecord oldTop = (HistoryRecord)mHistory.get(top-1);
3027        mHistory.add(top, newTop);
3028        oldTop.frontOfTask = false;
3029        newTop.frontOfTask = true;
3030        return newTop;
3031    }
3032
3033    /**
3034     * Deliver a new Intent to an existing activity, so that its onNewIntent()
3035     * method will be called at the proper time.
3036     */
3037    private final void deliverNewIntentLocked(HistoryRecord r, Intent intent) {
3038        boolean sent = false;
3039        if (r.state == ActivityState.RESUMED
3040                && r.app != null && r.app.thread != null) {
3041            try {
3042                ArrayList<Intent> ar = new ArrayList<Intent>();
3043                ar.add(new Intent(intent));
3044                r.app.thread.scheduleNewIntent(ar, r);
3045                sent = true;
3046            } catch (Exception e) {
3047                Log.w(TAG, "Exception thrown sending new intent to " + r, e);
3048            }
3049        }
3050        if (!sent) {
3051            r.addNewIntentLocked(new Intent(intent));
3052        }
3053    }
3054
3055    private final void logStartActivity(int tag, HistoryRecord r,
3056            TaskRecord task) {
3057        EventLog.writeEvent(tag,
3058                System.identityHashCode(r), task.taskId,
3059                r.shortComponentName, r.intent.getAction(),
3060                r.intent.getType(), r.intent.getDataString(),
3061                r.intent.getFlags());
3062    }
3063
3064    private final int startActivityLocked(IApplicationThread caller,
3065            Intent intent, String resolvedType,
3066            Uri[] grantedUriPermissions,
3067            int grantedMode, ActivityInfo aInfo, IBinder resultTo,
3068            String resultWho, int requestCode,
3069            int callingPid, int callingUid, boolean onlyIfNeeded,
3070            boolean componentSpecified) {
3071        Log.i(TAG, "Starting activity: " + intent);
3072
3073        HistoryRecord sourceRecord = null;
3074        HistoryRecord resultRecord = null;
3075        if (resultTo != null) {
3076            int index = indexOfTokenLocked(resultTo);
3077            if (DEBUG_RESULTS) Log.v(
3078                TAG, "Sending result to " + resultTo + " (index " + index + ")");
3079            if (index >= 0) {
3080                sourceRecord = (HistoryRecord)mHistory.get(index);
3081                if (requestCode >= 0 && !sourceRecord.finishing) {
3082                    resultRecord = sourceRecord;
3083                }
3084            }
3085        }
3086
3087        int launchFlags = intent.getFlags();
3088
3089        if ((launchFlags&Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0
3090                && sourceRecord != null) {
3091            // Transfer the result target from the source activity to the new
3092            // one being started, including any failures.
3093            if (requestCode >= 0) {
3094                return START_FORWARD_AND_REQUEST_CONFLICT;
3095            }
3096            resultRecord = sourceRecord.resultTo;
3097            resultWho = sourceRecord.resultWho;
3098            requestCode = sourceRecord.requestCode;
3099            sourceRecord.resultTo = null;
3100            if (resultRecord != null) {
3101                resultRecord.removeResultsLocked(
3102                    sourceRecord, resultWho, requestCode);
3103            }
3104        }
3105
3106        int err = START_SUCCESS;
3107
3108        if (intent.getComponent() == null) {
3109            // We couldn't find a class that can handle the given Intent.
3110            // That's the end of that!
3111            err = START_INTENT_NOT_RESOLVED;
3112        }
3113
3114        if (err == START_SUCCESS && aInfo == null) {
3115            // We couldn't find the specific class specified in the Intent.
3116            // Also the end of the line.
3117            err = START_CLASS_NOT_FOUND;
3118        }
3119
3120        ProcessRecord callerApp = null;
3121        if (err == START_SUCCESS && caller != null) {
3122            callerApp = getRecordForAppLocked(caller);
3123            if (callerApp != null) {
3124                callingPid = callerApp.pid;
3125                callingUid = callerApp.info.uid;
3126            } else {
3127                Log.w(TAG, "Unable to find app for caller " + caller
3128                      + " (pid=" + callingPid + ") when starting: "
3129                      + intent.toString());
3130                err = START_PERMISSION_DENIED;
3131            }
3132        }
3133
3134        if (err != START_SUCCESS) {
3135            if (resultRecord != null) {
3136                sendActivityResultLocked(-1,
3137                    resultRecord, resultWho, requestCode,
3138                    Activity.RESULT_CANCELED, null);
3139            }
3140            return err;
3141        }
3142
3143        final int perm = checkComponentPermission(aInfo.permission, callingPid,
3144                callingUid, aInfo.exported ? -1 : aInfo.applicationInfo.uid);
3145        if (perm != PackageManager.PERMISSION_GRANTED) {
3146            if (resultRecord != null) {
3147                sendActivityResultLocked(-1,
3148                    resultRecord, resultWho, requestCode,
3149                    Activity.RESULT_CANCELED, null);
3150            }
3151            String msg = "Permission Denial: starting " + intent.toString()
3152                    + " from " + callerApp + " (pid=" + callingPid
3153                    + ", uid=" + callingUid + ")"
3154                    + " requires " + aInfo.permission;
3155            Log.w(TAG, msg);
3156            throw new SecurityException(msg);
3157        }
3158
3159        if (mController != null) {
3160            boolean abort = false;
3161            try {
3162                // The Intent we give to the watcher has the extra data
3163                // stripped off, since it can contain private information.
3164                Intent watchIntent = intent.cloneFilter();
3165                abort = !mController.activityStarting(watchIntent,
3166                        aInfo.applicationInfo.packageName);
3167            } catch (RemoteException e) {
3168                mController = null;
3169            }
3170
3171            if (abort) {
3172                if (resultRecord != null) {
3173                    sendActivityResultLocked(-1,
3174                        resultRecord, resultWho, requestCode,
3175                        Activity.RESULT_CANCELED, null);
3176                }
3177                // We pretend to the caller that it was really started, but
3178                // they will just get a cancel result.
3179                return START_SUCCESS;
3180            }
3181        }
3182
3183        HistoryRecord r = new HistoryRecord(this, callerApp, callingUid,
3184                intent, resolvedType, aInfo, mConfiguration,
3185                resultRecord, resultWho, requestCode, componentSpecified);
3186
3187        if (mResumedActivity == null
3188                || mResumedActivity.info.applicationInfo.uid != callingUid) {
3189            if (!checkAppSwitchAllowedLocked(callingPid, callingUid, "Activity start")) {
3190                PendingActivityLaunch pal = new PendingActivityLaunch();
3191                pal.r = r;
3192                pal.sourceRecord = sourceRecord;
3193                pal.grantedUriPermissions = grantedUriPermissions;
3194                pal.grantedMode = grantedMode;
3195                pal.onlyIfNeeded = onlyIfNeeded;
3196                mPendingActivityLaunches.add(pal);
3197                return START_SWITCHES_CANCELED;
3198            }
3199        }
3200
3201        if (mDidAppSwitch) {
3202            // This is the second allowed switch since we stopped switches,
3203            // so now just generally allow switches.  Use case: user presses
3204            // home (switches disabled, switch to home, mDidAppSwitch now true);
3205            // user taps a home icon (coming from home so allowed, we hit here
3206            // and now allow anyone to switch again).
3207            mAppSwitchesAllowedTime = 0;
3208        } else {
3209            mDidAppSwitch = true;
3210        }
3211
3212        doPendingActivityLaunchesLocked(false);
3213
3214        return startActivityUncheckedLocked(r, sourceRecord,
3215                grantedUriPermissions, grantedMode, onlyIfNeeded, true);
3216    }
3217
3218    private final void doPendingActivityLaunchesLocked(boolean doResume) {
3219        final int N = mPendingActivityLaunches.size();
3220        if (N <= 0) {
3221            return;
3222        }
3223        for (int i=0; i<N; i++) {
3224            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
3225            startActivityUncheckedLocked(pal.r, pal.sourceRecord,
3226                    pal.grantedUriPermissions, pal.grantedMode, pal.onlyIfNeeded,
3227                    doResume && i == (N-1));
3228        }
3229        mPendingActivityLaunches.clear();
3230    }
3231
3232    private final int startActivityUncheckedLocked(HistoryRecord r,
3233            HistoryRecord sourceRecord, Uri[] grantedUriPermissions,
3234            int grantedMode, boolean onlyIfNeeded, boolean doResume) {
3235        final Intent intent = r.intent;
3236        final int callingUid = r.launchedFromUid;
3237
3238        int launchFlags = intent.getFlags();
3239
3240        // We'll invoke onUserLeaving before onPause only if the launching
3241        // activity did not explicitly state that this is an automated launch.
3242        mUserLeaving = (launchFlags&Intent.FLAG_ACTIVITY_NO_USER_ACTION) == 0;
3243        if (DEBUG_USER_LEAVING) Log.v(TAG,
3244                "startActivity() => mUserLeaving=" + mUserLeaving);
3245
3246        // If the caller has asked not to resume at this point, we make note
3247        // of this in the record so that we can skip it when trying to find
3248        // the top running activity.
3249        if (!doResume) {
3250            r.delayedResume = true;
3251        }
3252
3253        HistoryRecord notTop = (launchFlags&Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP)
3254                != 0 ? r : null;
3255
3256        // If the onlyIfNeeded flag is set, then we can do this if the activity
3257        // being launched is the same as the one making the call...  or, as
3258        // a special case, if we do not know the caller then we count the
3259        // current top activity as the caller.
3260        if (onlyIfNeeded) {
3261            HistoryRecord checkedCaller = sourceRecord;
3262            if (checkedCaller == null) {
3263                checkedCaller = topRunningNonDelayedActivityLocked(notTop);
3264            }
3265            if (!checkedCaller.realActivity.equals(r.realActivity)) {
3266                // Caller is not the same as launcher, so always needed.
3267                onlyIfNeeded = false;
3268            }
3269        }
3270
3271        if (grantedUriPermissions != null && callingUid > 0) {
3272            for (int i=0; i<grantedUriPermissions.length; i++) {
3273                grantUriPermissionLocked(callingUid, r.packageName,
3274                        grantedUriPermissions[i], grantedMode, r);
3275            }
3276        }
3277
3278        grantUriPermissionFromIntentLocked(callingUid, r.packageName,
3279                intent, r);
3280
3281        if (sourceRecord == null) {
3282            // This activity is not being started from another...  in this
3283            // case we -always- start a new task.
3284            if ((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
3285                Log.w(TAG, "startActivity called from non-Activity context; forcing Intent.FLAG_ACTIVITY_NEW_TASK for: "
3286                      + intent);
3287                launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
3288            }
3289        } else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
3290            // The original activity who is starting us is running as a single
3291            // instance...  this new activity it is starting must go on its
3292            // own task.
3293            launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
3294        } else if (r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE
3295                || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
3296            // The activity being started is a single instance...  it always
3297            // gets launched into its own task.
3298            launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
3299        }
3300
3301        if (r.resultTo != null && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
3302            // For whatever reason this activity is being launched into a new
3303            // task...  yet the caller has requested a result back.  Well, that
3304            // is pretty messed up, so instead immediately send back a cancel
3305            // and let the new task continue launched as normal without a
3306            // dependency on its originator.
3307            Log.w(TAG, "Activity is launching as a new task, so cancelling activity result.");
3308            sendActivityResultLocked(-1,
3309                    r.resultTo, r.resultWho, r.requestCode,
3310                Activity.RESULT_CANCELED, null);
3311            r.resultTo = null;
3312        }
3313
3314        boolean addingToTask = false;
3315        if (((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0 &&
3316                (launchFlags&Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
3317                || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
3318                || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
3319            // If bring to front is requested, and no result is requested, and
3320            // we can find a task that was started with this same
3321            // component, then instead of launching bring that one to the front.
3322            if (r.resultTo == null) {
3323                // See if there is a task to bring to the front.  If this is
3324                // a SINGLE_INSTANCE activity, there can be one and only one
3325                // instance of it in the history, and it is always in its own
3326                // unique task, so we do a special search.
3327                HistoryRecord taskTop = r.launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE
3328                        ? findTaskLocked(intent, r.info)
3329                        : findActivityLocked(intent, r.info);
3330                if (taskTop != null) {
3331                    if (taskTop.task.intent == null) {
3332                        // This task was started because of movement of
3333                        // the activity based on affinity...  now that we
3334                        // are actually launching it, we can assign the
3335                        // base intent.
3336                        taskTop.task.setIntent(intent, r.info);
3337                    }
3338                    // If the target task is not in the front, then we need
3339                    // to bring it to the front...  except...  well, with
3340                    // SINGLE_TASK_LAUNCH it's not entirely clear.  We'd like
3341                    // to have the same behavior as if a new instance was
3342                    // being started, which means not bringing it to the front
3343                    // if the caller is not itself in the front.
3344                    HistoryRecord curTop = topRunningNonDelayedActivityLocked(notTop);
3345                    if (curTop.task != taskTop.task) {
3346                        r.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
3347                        boolean callerAtFront = sourceRecord == null
3348                                || curTop.task == sourceRecord.task;
3349                        if (callerAtFront) {
3350                            // We really do want to push this one into the
3351                            // user's face, right now.
3352                            moveTaskToFrontLocked(taskTop.task, r);
3353                        }
3354                    }
3355                    // If the caller has requested that the target task be
3356                    // reset, then do so.
3357                    if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
3358                        taskTop = resetTaskIfNeededLocked(taskTop, r);
3359                    }
3360                    if (onlyIfNeeded) {
3361                        // We don't need to start a new activity, and
3362                        // the client said not to do anything if that
3363                        // is the case, so this is it!  And for paranoia, make
3364                        // sure we have correctly resumed the top activity.
3365                        if (doResume) {
3366                            resumeTopActivityLocked(null);
3367                        }
3368                        return START_RETURN_INTENT_TO_CALLER;
3369                    }
3370                    if ((launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0
3371                            || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
3372                            || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
3373                        // In this situation we want to remove all activities
3374                        // from the task up to the one being started.  In most
3375                        // cases this means we are resetting the task to its
3376                        // initial state.
3377                        HistoryRecord top = performClearTaskLocked(
3378                                taskTop.task.taskId, r, launchFlags, true);
3379                        if (top != null) {
3380                            if (top.frontOfTask) {
3381                                // Activity aliases may mean we use different
3382                                // intents for the top activity, so make sure
3383                                // the task now has the identity of the new
3384                                // intent.
3385                                top.task.setIntent(r.intent, r.info);
3386                            }
3387                            logStartActivity(EventLogTags.AM_NEW_INTENT, r, top.task);
3388                            deliverNewIntentLocked(top, r.intent);
3389                        } else {
3390                            // A special case: we need to
3391                            // start the activity because it is not currently
3392                            // running, and the caller has asked to clear the
3393                            // current task to have this activity at the top.
3394                            addingToTask = true;
3395                            // Now pretend like this activity is being started
3396                            // by the top of its task, so it is put in the
3397                            // right place.
3398                            sourceRecord = taskTop;
3399                        }
3400                    } else if (r.realActivity.equals(taskTop.task.realActivity)) {
3401                        // In this case the top activity on the task is the
3402                        // same as the one being launched, so we take that
3403                        // as a request to bring the task to the foreground.
3404                        // If the top activity in the task is the root
3405                        // activity, deliver this new intent to it if it
3406                        // desires.
3407                        if ((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
3408                                && taskTop.realActivity.equals(r.realActivity)) {
3409                            logStartActivity(EventLogTags.AM_NEW_INTENT, r, taskTop.task);
3410                            if (taskTop.frontOfTask) {
3411                                taskTop.task.setIntent(r.intent, r.info);
3412                            }
3413                            deliverNewIntentLocked(taskTop, r.intent);
3414                        } else if (!r.intent.filterEquals(taskTop.task.intent)) {
3415                            // In this case we are launching the root activity
3416                            // of the task, but with a different intent.  We
3417                            // should start a new instance on top.
3418                            addingToTask = true;
3419                            sourceRecord = taskTop;
3420                        }
3421                    } else if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0) {
3422                        // In this case an activity is being launched in to an
3423                        // existing task, without resetting that task.  This
3424                        // is typically the situation of launching an activity
3425                        // from a notification or shortcut.  We want to place
3426                        // the new activity on top of the current task.
3427                        addingToTask = true;
3428                        sourceRecord = taskTop;
3429                    } else if (!taskTop.task.rootWasReset) {
3430                        // In this case we are launching in to an existing task
3431                        // that has not yet been started from its front door.
3432                        // The current task has been brought to the front.
3433                        // Ideally, we'd probably like to place this new task
3434                        // at the bottom of its stack, but that's a little hard
3435                        // to do with the current organization of the code so
3436                        // for now we'll just drop it.
3437                        taskTop.task.setIntent(r.intent, r.info);
3438                    }
3439                    if (!addingToTask) {
3440                        // We didn't do anything...  but it was needed (a.k.a., client
3441                        // don't use that intent!)  And for paranoia, make
3442                        // sure we have correctly resumed the top activity.
3443                        if (doResume) {
3444                            resumeTopActivityLocked(null);
3445                        }
3446                        return START_TASK_TO_FRONT;
3447                    }
3448                }
3449            }
3450        }
3451
3452        //String uri = r.intent.toURI();
3453        //Intent intent2 = new Intent(uri);
3454        //Log.i(TAG, "Given intent: " + r.intent);
3455        //Log.i(TAG, "URI is: " + uri);
3456        //Log.i(TAG, "To intent: " + intent2);
3457
3458        if (r.packageName != null) {
3459            // If the activity being launched is the same as the one currently
3460            // at the top, then we need to check if it should only be launched
3461            // once.
3462            HistoryRecord top = topRunningNonDelayedActivityLocked(notTop);
3463            if (top != null && r.resultTo == null) {
3464                if (top.realActivity.equals(r.realActivity)) {
3465                    if (top.app != null && top.app.thread != null) {
3466                        if ((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
3467                            || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP
3468                            || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
3469                            logStartActivity(EventLogTags.AM_NEW_INTENT, top, top.task);
3470                            // For paranoia, make sure we have correctly
3471                            // resumed the top activity.
3472                            if (doResume) {
3473                                resumeTopActivityLocked(null);
3474                            }
3475                            if (onlyIfNeeded) {
3476                                // We don't need to start a new activity, and
3477                                // the client said not to do anything if that
3478                                // is the case, so this is it!
3479                                return START_RETURN_INTENT_TO_CALLER;
3480                            }
3481                            deliverNewIntentLocked(top, r.intent);
3482                            return START_DELIVERED_TO_TOP;
3483                        }
3484                    }
3485                }
3486            }
3487
3488        } else {
3489            if (r.resultTo != null) {
3490                sendActivityResultLocked(-1,
3491                        r.resultTo, r.resultWho, r.requestCode,
3492                    Activity.RESULT_CANCELED, null);
3493            }
3494            return START_CLASS_NOT_FOUND;
3495        }
3496
3497        boolean newTask = false;
3498
3499        // Should this be considered a new task?
3500        if (r.resultTo == null && !addingToTask
3501                && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
3502            // todo: should do better management of integers.
3503            mCurTask++;
3504            if (mCurTask <= 0) {
3505                mCurTask = 1;
3506            }
3507            r.task = new TaskRecord(mCurTask, r.info, intent,
3508                    (r.info.flags&ActivityInfo.FLAG_CLEAR_TASK_ON_LAUNCH) != 0);
3509            if (DEBUG_TASKS) Log.v(TAG, "Starting new activity " + r
3510                    + " in new task " + r.task);
3511            newTask = true;
3512            addRecentTask(r.task);
3513
3514        } else if (sourceRecord != null) {
3515            if (!addingToTask &&
3516                    (launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
3517                // In this case, we are adding the activity to an existing
3518                // task, but the caller has asked to clear that task if the
3519                // activity is already running.
3520                HistoryRecord top = performClearTaskLocked(
3521                        sourceRecord.task.taskId, r, launchFlags, true);
3522                if (top != null) {
3523                    logStartActivity(EventLogTags.AM_NEW_INTENT, r, top.task);
3524                    deliverNewIntentLocked(top, r.intent);
3525                    // For paranoia, make sure we have correctly
3526                    // resumed the top activity.
3527                    if (doResume) {
3528                        resumeTopActivityLocked(null);
3529                    }
3530                    return START_DELIVERED_TO_TOP;
3531                }
3532            } else if (!addingToTask &&
3533                    (launchFlags&Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) {
3534                // In this case, we are launching an activity in our own task
3535                // that may already be running somewhere in the history, and
3536                // we want to shuffle it to the front of the stack if so.
3537                int where = findActivityInHistoryLocked(r, sourceRecord.task.taskId);
3538                if (where >= 0) {
3539                    HistoryRecord top = moveActivityToFrontLocked(where);
3540                    logStartActivity(EventLogTags.AM_NEW_INTENT, r, top.task);
3541                    deliverNewIntentLocked(top, r.intent);
3542                    if (doResume) {
3543                        resumeTopActivityLocked(null);
3544                    }
3545                    return START_DELIVERED_TO_TOP;
3546                }
3547            }
3548            // An existing activity is starting this new activity, so we want
3549            // to keep the new one in the same task as the one that is starting
3550            // it.
3551            r.task = sourceRecord.task;
3552            if (DEBUG_TASKS) Log.v(TAG, "Starting new activity " + r
3553                    + " in existing task " + r.task);
3554
3555        } else {
3556            // This not being started from an existing activity, and not part
3557            // of a new task...  just put it in the top task, though these days
3558            // this case should never happen.
3559            final int N = mHistory.size();
3560            HistoryRecord prev =
3561                N > 0 ? (HistoryRecord)mHistory.get(N-1) : null;
3562            r.task = prev != null
3563                ? prev.task
3564                : new TaskRecord(mCurTask, r.info, intent,
3565                        (r.info.flags&ActivityInfo.FLAG_CLEAR_TASK_ON_LAUNCH) != 0);
3566            if (DEBUG_TASKS) Log.v(TAG, "Starting new activity " + r
3567                    + " in new guessed " + r.task);
3568        }
3569        if (newTask) {
3570            EventLog.writeEvent(EventLogTags.AM_CREATE_TASK, r.task.taskId);
3571        }
3572        logStartActivity(EventLogTags.AM_CREATE_ACTIVITY, r, r.task);
3573        startActivityLocked(r, newTask, doResume);
3574        return START_SUCCESS;
3575    }
3576
3577    public final int startActivity(IApplicationThread caller,
3578            Intent intent, String resolvedType, Uri[] grantedUriPermissions,
3579            int grantedMode, IBinder resultTo,
3580            String resultWho, int requestCode, boolean onlyIfNeeded,
3581            boolean debug) {
3582        // Refuse possible leaked file descriptors
3583        if (intent != null && intent.hasFileDescriptors()) {
3584            throw new IllegalArgumentException("File descriptors passed in Intent");
3585        }
3586
3587        final boolean componentSpecified = intent.getComponent() != null;
3588
3589        // Don't modify the client's object!
3590        intent = new Intent(intent);
3591
3592        // Collect information about the target of the Intent.
3593        ActivityInfo aInfo;
3594        try {
3595            ResolveInfo rInfo =
3596                ActivityThread.getPackageManager().resolveIntent(
3597                        intent, resolvedType,
3598                        PackageManager.MATCH_DEFAULT_ONLY
3599                        | STOCK_PM_FLAGS);
3600            aInfo = rInfo != null ? rInfo.activityInfo : null;
3601        } catch (RemoteException e) {
3602            aInfo = null;
3603        }
3604
3605        if (aInfo != null) {
3606            // Store the found target back into the intent, because now that
3607            // we have it we never want to do this again.  For example, if the
3608            // user navigates back to this point in the history, we should
3609            // always restart the exact same activity.
3610            intent.setComponent(new ComponentName(
3611                    aInfo.applicationInfo.packageName, aInfo.name));
3612
3613            // Don't debug things in the system process
3614            if (debug) {
3615                if (!aInfo.processName.equals("system")) {
3616                    setDebugApp(aInfo.processName, true, false);
3617                }
3618            }
3619        }
3620
3621        synchronized(this) {
3622            final long origId = Binder.clearCallingIdentity();
3623            int res = startActivityLocked(caller, intent, resolvedType,
3624                    grantedUriPermissions, grantedMode, aInfo,
3625                    resultTo, resultWho, requestCode, -1, -1,
3626                    onlyIfNeeded, componentSpecified);
3627            Binder.restoreCallingIdentity(origId);
3628            return res;
3629        }
3630    }
3631
3632    public int startActivityIntentSender(IApplicationThread caller,
3633            IntentSender intent, Intent fillInIntent, String resolvedType,
3634            IBinder resultTo, String resultWho, int requestCode,
3635            int flagsMask, int flagsValues) {
3636        // Refuse possible leaked file descriptors
3637        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3638            throw new IllegalArgumentException("File descriptors passed in Intent");
3639        }
3640
3641        IIntentSender sender = intent.getTarget();
3642        if (!(sender instanceof PendingIntentRecord)) {
3643            throw new IllegalArgumentException("Bad PendingIntent object");
3644        }
3645
3646        PendingIntentRecord pir = (PendingIntentRecord)sender;
3647
3648        synchronized (this) {
3649            // If this is coming from the currently resumed activity, it is
3650            // effectively saying that app switches are allowed at this point.
3651            if (mResumedActivity != null
3652                    && mResumedActivity.info.applicationInfo.uid ==
3653                            Binder.getCallingUid()) {
3654                mAppSwitchesAllowedTime = 0;
3655            }
3656        }
3657
3658        return pir.sendInner(0, fillInIntent, resolvedType,
3659                null, resultTo, resultWho, requestCode, flagsMask, flagsValues);
3660    }
3661
3662    public boolean startNextMatchingActivity(IBinder callingActivity,
3663            Intent intent) {
3664        // Refuse possible leaked file descriptors
3665        if (intent != null && intent.hasFileDescriptors() == true) {
3666            throw new IllegalArgumentException("File descriptors passed in Intent");
3667        }
3668
3669        synchronized (this) {
3670            int index = indexOfTokenLocked(callingActivity);
3671            if (index < 0) {
3672                return false;
3673            }
3674            HistoryRecord r = (HistoryRecord)mHistory.get(index);
3675            if (r.app == null || r.app.thread == null) {
3676                // The caller is not running...  d'oh!
3677                return false;
3678            }
3679            intent = new Intent(intent);
3680            // The caller is not allowed to change the data.
3681            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3682            // And we are resetting to find the next component...
3683            intent.setComponent(null);
3684
3685            ActivityInfo aInfo = null;
3686            try {
3687                List<ResolveInfo> resolves =
3688                    ActivityThread.getPackageManager().queryIntentActivities(
3689                            intent, r.resolvedType,
3690                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS);
3691
3692                // Look for the original activity in the list...
3693                final int N = resolves != null ? resolves.size() : 0;
3694                for (int i=0; i<N; i++) {
3695                    ResolveInfo rInfo = resolves.get(i);
3696                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3697                            && rInfo.activityInfo.name.equals(r.info.name)) {
3698                        // We found the current one...  the next matching is
3699                        // after it.
3700                        i++;
3701                        if (i<N) {
3702                            aInfo = resolves.get(i).activityInfo;
3703                        }
3704                        break;
3705                    }
3706                }
3707            } catch (RemoteException e) {
3708            }
3709
3710            if (aInfo == null) {
3711                // Nobody who is next!
3712                return false;
3713            }
3714
3715            intent.setComponent(new ComponentName(
3716                    aInfo.applicationInfo.packageName, aInfo.name));
3717            intent.setFlags(intent.getFlags()&~(
3718                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3719                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3720                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3721                    Intent.FLAG_ACTIVITY_NEW_TASK));
3722
3723            // Okay now we need to start the new activity, replacing the
3724            // currently running activity.  This is a little tricky because
3725            // we want to start the new one as if the current one is finished,
3726            // but not finish the current one first so that there is no flicker.
3727            // And thus...
3728            final boolean wasFinishing = r.finishing;
3729            r.finishing = true;
3730
3731            // Propagate reply information over to the new activity.
3732            final HistoryRecord resultTo = r.resultTo;
3733            final String resultWho = r.resultWho;
3734            final int requestCode = r.requestCode;
3735            r.resultTo = null;
3736            if (resultTo != null) {
3737                resultTo.removeResultsLocked(r, resultWho, requestCode);
3738            }
3739
3740            final long origId = Binder.clearCallingIdentity();
3741            // XXX we are not dealing with propagating grantedUriPermissions...
3742            // those are not yet exposed to user code, so there is no need.
3743            int res = startActivityLocked(r.app.thread, intent,
3744                    r.resolvedType, null, 0, aInfo, resultTo, resultWho,
3745                    requestCode, -1, r.launchedFromUid, false, false);
3746            Binder.restoreCallingIdentity(origId);
3747
3748            r.finishing = wasFinishing;
3749            if (res != START_SUCCESS) {
3750                return false;
3751            }
3752            return true;
3753        }
3754    }
3755
3756    public final int startActivityInPackage(int uid,
3757            Intent intent, String resolvedType, IBinder resultTo,
3758            String resultWho, int requestCode, boolean onlyIfNeeded) {
3759
3760        // This is so super not safe, that only the system (or okay root)
3761        // can do it.
3762        final int callingUid = Binder.getCallingUid();
3763        if (callingUid != 0 && callingUid != Process.myUid()) {
3764            throw new SecurityException(
3765                    "startActivityInPackage only available to the system");
3766        }
3767
3768        final boolean componentSpecified = intent.getComponent() != null;
3769
3770        // Don't modify the client's object!
3771        intent = new Intent(intent);
3772
3773        // Collect information about the target of the Intent.
3774        ActivityInfo aInfo;
3775        try {
3776            ResolveInfo rInfo =
3777                ActivityThread.getPackageManager().resolveIntent(
3778                        intent, resolvedType,
3779                        PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS);
3780            aInfo = rInfo != null ? rInfo.activityInfo : null;
3781        } catch (RemoteException e) {
3782            aInfo = null;
3783        }
3784
3785        if (aInfo != null) {
3786            // Store the found target back into the intent, because now that
3787            // we have it we never want to do this again.  For example, if the
3788            // user navigates back to this point in the history, we should
3789            // always restart the exact same activity.
3790            intent.setComponent(new ComponentName(
3791                    aInfo.applicationInfo.packageName, aInfo.name));
3792        }
3793
3794        synchronized(this) {
3795            return startActivityLocked(null, intent, resolvedType,
3796                    null, 0, aInfo, resultTo, resultWho, requestCode, -1, uid,
3797                    onlyIfNeeded, componentSpecified);
3798        }
3799    }
3800
3801    private final void addRecentTask(TaskRecord task) {
3802        // Remove any existing entries that are the same kind of task.
3803        int N = mRecentTasks.size();
3804        for (int i=0; i<N; i++) {
3805            TaskRecord tr = mRecentTasks.get(i);
3806            if ((task.affinity != null && task.affinity.equals(tr.affinity))
3807                    || (task.intent != null && task.intent.filterEquals(tr.intent))) {
3808                mRecentTasks.remove(i);
3809                i--;
3810                N--;
3811                if (task.intent == null) {
3812                    // If the new recent task we are adding is not fully
3813                    // specified, then replace it with the existing recent task.
3814                    task = tr;
3815                }
3816            }
3817        }
3818        if (N >= MAX_RECENT_TASKS) {
3819            mRecentTasks.remove(N-1);
3820        }
3821        mRecentTasks.add(0, task);
3822    }
3823
3824    public void setRequestedOrientation(IBinder token,
3825            int requestedOrientation) {
3826        synchronized (this) {
3827            int index = indexOfTokenLocked(token);
3828            if (index < 0) {
3829                return;
3830            }
3831            HistoryRecord r = (HistoryRecord)mHistory.get(index);
3832            final long origId = Binder.clearCallingIdentity();
3833            mWindowManager.setAppOrientation(r, requestedOrientation);
3834            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3835                    mConfiguration,
3836                    r.mayFreezeScreenLocked(r.app) ? r : null);
3837            if (config != null) {
3838                r.frozenBeforeDestroy = true;
3839                if (!updateConfigurationLocked(config, r)) {
3840                    resumeTopActivityLocked(null);
3841                }
3842            }
3843            Binder.restoreCallingIdentity(origId);
3844        }
3845    }
3846
3847    public int getRequestedOrientation(IBinder token) {
3848        synchronized (this) {
3849            int index = indexOfTokenLocked(token);
3850            if (index < 0) {
3851                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3852            }
3853            HistoryRecord r = (HistoryRecord)mHistory.get(index);
3854            return mWindowManager.getAppOrientation(r);
3855        }
3856    }
3857
3858    private final void stopActivityLocked(HistoryRecord r) {
3859        if (DEBUG_SWITCH) Log.d(TAG, "Stopping: " + r);
3860        if ((r.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_HISTORY) != 0
3861                || (r.info.flags&ActivityInfo.FLAG_NO_HISTORY) != 0) {
3862            if (!r.finishing) {
3863                requestFinishActivityLocked(r, Activity.RESULT_CANCELED, null,
3864                        "no-history");
3865            }
3866        } else if (r.app != null && r.app.thread != null) {
3867            if (mFocusedActivity == r) {
3868                setFocusedActivityLocked(topRunningActivityLocked(null));
3869            }
3870            r.resumeKeyDispatchingLocked();
3871            try {
3872                r.stopped = false;
3873                r.state = ActivityState.STOPPING;
3874                if (DEBUG_VISBILITY) Log.v(
3875                        TAG, "Stopping visible=" + r.visible + " for " + r);
3876                if (!r.visible) {
3877                    mWindowManager.setAppVisibility(r, false);
3878                }
3879                r.app.thread.scheduleStopActivity(r, r.visible, r.configChangeFlags);
3880            } catch (Exception e) {
3881                // Maybe just ignore exceptions here...  if the process
3882                // has crashed, our death notification will clean things
3883                // up.
3884                Log.w(TAG, "Exception thrown during pause", e);
3885                // Just in case, assume it to be stopped.
3886                r.stopped = true;
3887                r.state = ActivityState.STOPPED;
3888                if (r.configDestroy) {
3889                    destroyActivityLocked(r, true);
3890                }
3891            }
3892        }
3893    }
3894
3895    /**
3896     * @return Returns true if the activity is being finished, false if for
3897     * some reason it is being left as-is.
3898     */
3899    private final boolean requestFinishActivityLocked(IBinder token, int resultCode,
3900            Intent resultData, String reason) {
3901        if (DEBUG_RESULTS) Log.v(
3902            TAG, "Finishing activity: token=" + token
3903            + ", result=" + resultCode + ", data=" + resultData);
3904
3905        int index = indexOfTokenLocked(token);
3906        if (index < 0) {
3907            return false;
3908        }
3909        HistoryRecord r = (HistoryRecord)mHistory.get(index);
3910
3911        // Is this the last activity left?
3912        boolean lastActivity = true;
3913        for (int i=mHistory.size()-1; i>=0; i--) {
3914            HistoryRecord p = (HistoryRecord)mHistory.get(i);
3915            if (!p.finishing && p != r) {
3916                lastActivity = false;
3917                break;
3918            }
3919        }
3920
3921        // If this is the last activity, but it is the home activity, then
3922        // just don't finish it.
3923        if (lastActivity) {
3924            if (r.intent.hasCategory(Intent.CATEGORY_HOME)) {
3925                return false;
3926            }
3927        }
3928
3929        finishActivityLocked(r, index, resultCode, resultData, reason);
3930        return true;
3931    }
3932
3933    /**
3934     * @return Returns true if this activity has been removed from the history
3935     * list, or false if it is still in the list and will be removed later.
3936     */
3937    private final boolean finishActivityLocked(HistoryRecord r, int index,
3938            int resultCode, Intent resultData, String reason) {
3939        if (r.finishing) {
3940            Log.w(TAG, "Duplicate finish request for " + r);
3941            return false;
3942        }
3943
3944        r.finishing = true;
3945        EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY,
3946                System.identityHashCode(r),
3947                r.task.taskId, r.shortComponentName, reason);
3948        r.task.numActivities--;
3949        if (r.frontOfTask && index < (mHistory.size()-1)) {
3950            HistoryRecord next = (HistoryRecord)mHistory.get(index+1);
3951            if (next.task == r.task) {
3952                next.frontOfTask = true;
3953            }
3954        }
3955
3956        r.pauseKeyDispatchingLocked();
3957        if (mFocusedActivity == r) {
3958            setFocusedActivityLocked(topRunningActivityLocked(null));
3959        }
3960
3961        // send the result
3962        HistoryRecord resultTo = r.resultTo;
3963        if (resultTo != null) {
3964            if (DEBUG_RESULTS) Log.v(TAG, "Adding result to " + resultTo
3965                    + " who=" + r.resultWho + " req=" + r.requestCode
3966                    + " res=" + resultCode + " data=" + resultData);
3967            if (r.info.applicationInfo.uid > 0) {
3968                grantUriPermissionFromIntentLocked(r.info.applicationInfo.uid,
3969                        r.packageName, resultData, r);
3970            }
3971            resultTo.addResultLocked(r, r.resultWho, r.requestCode, resultCode,
3972                                     resultData);
3973            r.resultTo = null;
3974        }
3975        else if (DEBUG_RESULTS) Log.v(TAG, "No result destination from " + r);
3976
3977        // Make sure this HistoryRecord is not holding on to other resources,
3978        // because clients have remote IPC references to this object so we
3979        // can't assume that will go away and want to avoid circular IPC refs.
3980        r.results = null;
3981        r.pendingResults = null;
3982        r.newIntents = null;
3983        r.icicle = null;
3984
3985        if (mPendingThumbnails.size() > 0) {
3986            // There are clients waiting to receive thumbnails so, in case
3987            // this is an activity that someone is waiting for, add it
3988            // to the pending list so we can correctly update the clients.
3989            mCancelledThumbnails.add(r);
3990        }
3991
3992        if (mResumedActivity == r) {
3993            boolean endTask = index <= 0
3994                    || ((HistoryRecord)mHistory.get(index-1)).task != r.task;
3995            if (DEBUG_TRANSITION) Log.v(TAG,
3996                    "Prepare close transition: finishing " + r);
3997            mWindowManager.prepareAppTransition(endTask
3998                    ? WindowManagerPolicy.TRANSIT_TASK_CLOSE
3999                    : WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE);
4000
4001            // Tell window manager to prepare for this one to be removed.
4002            mWindowManager.setAppVisibility(r, false);
4003
4004            if (mPausingActivity == null) {
4005                if (DEBUG_PAUSE) Log.v(TAG, "Finish needs to pause: " + r);
4006                if (DEBUG_USER_LEAVING) Log.v(TAG, "finish() => pause with userLeaving=false");
4007                startPausingLocked(false, false);
4008            }
4009
4010        } else if (r.state != ActivityState.PAUSING) {
4011            // If the activity is PAUSING, we will complete the finish once
4012            // it is done pausing; else we can just directly finish it here.
4013            if (DEBUG_PAUSE) Log.v(TAG, "Finish not pausing: " + r);
4014            return finishCurrentActivityLocked(r, index,
4015                    FINISH_AFTER_PAUSE) == null;
4016        } else {
4017            if (DEBUG_PAUSE) Log.v(TAG, "Finish waiting for pause of: " + r);
4018        }
4019
4020        return false;
4021    }
4022
4023    private static final int FINISH_IMMEDIATELY = 0;
4024    private static final int FINISH_AFTER_PAUSE = 1;
4025    private static final int FINISH_AFTER_VISIBLE = 2;
4026
4027    private final HistoryRecord finishCurrentActivityLocked(HistoryRecord r,
4028            int mode) {
4029        final int index = indexOfTokenLocked(r);
4030        if (index < 0) {
4031            return null;
4032        }
4033
4034        return finishCurrentActivityLocked(r, index, mode);
4035    }
4036
4037    private final HistoryRecord finishCurrentActivityLocked(HistoryRecord r,
4038            int index, int mode) {
4039        // First things first: if this activity is currently visible,
4040        // and the resumed activity is not yet visible, then hold off on
4041        // finishing until the resumed one becomes visible.
4042        if (mode == FINISH_AFTER_VISIBLE && r.nowVisible) {
4043            if (!mStoppingActivities.contains(r)) {
4044                mStoppingActivities.add(r);
4045                if (mStoppingActivities.size() > 3) {
4046                    // If we already have a few activities waiting to stop,
4047                    // then give up on things going idle and start clearing
4048                    // them out.
4049                    Message msg = Message.obtain();
4050                    msg.what = ActivityManagerService.IDLE_NOW_MSG;
4051                    mHandler.sendMessage(msg);
4052                }
4053            }
4054            r.state = ActivityState.STOPPING;
4055            updateOomAdjLocked();
4056            return r;
4057        }
4058
4059        // make sure the record is cleaned out of other places.
4060        mStoppingActivities.remove(r);
4061        mWaitingVisibleActivities.remove(r);
4062        if (mResumedActivity == r) {
4063            mResumedActivity = null;
4064        }
4065        final ActivityState prevState = r.state;
4066        r.state = ActivityState.FINISHING;
4067
4068        if (mode == FINISH_IMMEDIATELY
4069                || prevState == ActivityState.STOPPED
4070                || prevState == ActivityState.INITIALIZING) {
4071            // If this activity is already stopped, we can just finish
4072            // it right now.
4073            return destroyActivityLocked(r, true) ? null : r;
4074        } else {
4075            // Need to go through the full pause cycle to get this
4076            // activity into the stopped state and then finish it.
4077            if (localLOGV) Log.v(TAG, "Enqueueing pending finish: " + r);
4078            mFinishingActivities.add(r);
4079            resumeTopActivityLocked(null);
4080        }
4081        return r;
4082    }
4083
4084    /**
4085     * This is the internal entry point for handling Activity.finish().
4086     *
4087     * @param token The Binder token referencing the Activity we want to finish.
4088     * @param resultCode Result code, if any, from this Activity.
4089     * @param resultData Result data (Intent), if any, from this Activity.
4090     *
4091     * @return Returns true if the activity successfully finished, or false if it is still running.
4092     */
4093    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
4094        // Refuse possible leaked file descriptors
4095        if (resultData != null && resultData.hasFileDescriptors() == true) {
4096            throw new IllegalArgumentException("File descriptors passed in Intent");
4097        }
4098
4099        synchronized(this) {
4100            if (mController != null) {
4101                // Find the first activity that is not finishing.
4102                HistoryRecord next = topRunningActivityLocked(token, 0);
4103                if (next != null) {
4104                    // ask watcher if this is allowed
4105                    boolean resumeOK = true;
4106                    try {
4107                        resumeOK = mController.activityResuming(next.packageName);
4108                    } catch (RemoteException e) {
4109                        mController = null;
4110                    }
4111
4112                    if (!resumeOK) {
4113                        return false;
4114                    }
4115                }
4116            }
4117            final long origId = Binder.clearCallingIdentity();
4118            boolean res = requestFinishActivityLocked(token, resultCode,
4119                    resultData, "app-request");
4120            Binder.restoreCallingIdentity(origId);
4121            return res;
4122        }
4123    }
4124
4125    void sendActivityResultLocked(int callingUid, HistoryRecord r,
4126            String resultWho, int requestCode, int resultCode, Intent data) {
4127
4128        if (callingUid > 0) {
4129            grantUriPermissionFromIntentLocked(callingUid, r.packageName,
4130                    data, r);
4131        }
4132
4133        if (DEBUG_RESULTS) Log.v(TAG, "Send activity result to " + r
4134                + " : who=" + resultWho + " req=" + requestCode
4135                + " res=" + resultCode + " data=" + data);
4136        if (mResumedActivity == r && r.app != null && r.app.thread != null) {
4137            try {
4138                ArrayList<ResultInfo> list = new ArrayList<ResultInfo>();
4139                list.add(new ResultInfo(resultWho, requestCode,
4140                        resultCode, data));
4141                r.app.thread.scheduleSendResult(r, list);
4142                return;
4143            } catch (Exception e) {
4144                Log.w(TAG, "Exception thrown sending result to " + r, e);
4145            }
4146        }
4147
4148        r.addResultLocked(null, resultWho, requestCode, resultCode, data);
4149    }
4150
4151    public final void finishSubActivity(IBinder token, String resultWho,
4152            int requestCode) {
4153        synchronized(this) {
4154            int index = indexOfTokenLocked(token);
4155            if (index < 0) {
4156                return;
4157            }
4158            HistoryRecord self = (HistoryRecord)mHistory.get(index);
4159
4160            final long origId = Binder.clearCallingIdentity();
4161
4162            int i;
4163            for (i=mHistory.size()-1; i>=0; i--) {
4164                HistoryRecord r = (HistoryRecord)mHistory.get(i);
4165                if (r.resultTo == self && r.requestCode == requestCode) {
4166                    if ((r.resultWho == null && resultWho == null) ||
4167                        (r.resultWho != null && r.resultWho.equals(resultWho))) {
4168                        finishActivityLocked(r, i,
4169                                Activity.RESULT_CANCELED, null, "request-sub");
4170                    }
4171                }
4172            }
4173
4174            Binder.restoreCallingIdentity(origId);
4175        }
4176    }
4177
4178    public void overridePendingTransition(IBinder token, String packageName,
4179            int enterAnim, int exitAnim) {
4180        synchronized(this) {
4181            int index = indexOfTokenLocked(token);
4182            if (index < 0) {
4183                return;
4184            }
4185            HistoryRecord self = (HistoryRecord)mHistory.get(index);
4186
4187            final long origId = Binder.clearCallingIdentity();
4188
4189            if (self.state == ActivityState.RESUMED
4190                    || self.state == ActivityState.PAUSING) {
4191                mWindowManager.overridePendingAppTransition(packageName,
4192                        enterAnim, exitAnim);
4193            }
4194
4195            Binder.restoreCallingIdentity(origId);
4196        }
4197    }
4198
4199    /**
4200     * Perform clean-up of service connections in an activity record.
4201     */
4202    private final void cleanUpActivityServicesLocked(HistoryRecord r) {
4203        // Throw away any services that have been bound by this activity.
4204        if (r.connections != null) {
4205            Iterator<ConnectionRecord> it = r.connections.iterator();
4206            while (it.hasNext()) {
4207                ConnectionRecord c = it.next();
4208                removeConnectionLocked(c, null, r);
4209            }
4210            r.connections = null;
4211        }
4212    }
4213
4214    /**
4215     * Perform the common clean-up of an activity record.  This is called both
4216     * as part of destroyActivityLocked() (when destroying the client-side
4217     * representation) and cleaning things up as a result of its hosting
4218     * processing going away, in which case there is no remaining client-side
4219     * state to destroy so only the cleanup here is needed.
4220     */
4221    private final void cleanUpActivityLocked(HistoryRecord r, boolean cleanServices) {
4222        if (mResumedActivity == r) {
4223            mResumedActivity = null;
4224        }
4225        if (mFocusedActivity == r) {
4226            mFocusedActivity = null;
4227        }
4228
4229        r.configDestroy = false;
4230        r.frozenBeforeDestroy = false;
4231
4232        // Make sure this record is no longer in the pending finishes list.
4233        // This could happen, for example, if we are trimming activities
4234        // down to the max limit while they are still waiting to finish.
4235        mFinishingActivities.remove(r);
4236        mWaitingVisibleActivities.remove(r);
4237
4238        // Remove any pending results.
4239        if (r.finishing && r.pendingResults != null) {
4240            for (WeakReference<PendingIntentRecord> apr : r.pendingResults) {
4241                PendingIntentRecord rec = apr.get();
4242                if (rec != null) {
4243                    cancelIntentSenderLocked(rec, false);
4244                }
4245            }
4246            r.pendingResults = null;
4247        }
4248
4249        if (cleanServices) {
4250            cleanUpActivityServicesLocked(r);
4251        }
4252
4253        if (mPendingThumbnails.size() > 0) {
4254            // There are clients waiting to receive thumbnails so, in case
4255            // this is an activity that someone is waiting for, add it
4256            // to the pending list so we can correctly update the clients.
4257            mCancelledThumbnails.add(r);
4258        }
4259
4260        // Get rid of any pending idle timeouts.
4261        mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);
4262        mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
4263    }
4264
4265    private final void removeActivityFromHistoryLocked(HistoryRecord r) {
4266        if (r.state != ActivityState.DESTROYED) {
4267            mHistory.remove(r);
4268            r.inHistory = false;
4269            r.state = ActivityState.DESTROYED;
4270            mWindowManager.removeAppToken(r);
4271            if (VALIDATE_TOKENS) {
4272                mWindowManager.validateAppTokens(mHistory);
4273            }
4274            cleanUpActivityServicesLocked(r);
4275            removeActivityUriPermissionsLocked(r);
4276        }
4277    }
4278
4279    /**
4280     * Destroy the current CLIENT SIDE instance of an activity.  This may be
4281     * called both when actually finishing an activity, or when performing
4282     * a configuration switch where we destroy the current client-side object
4283     * but then create a new client-side object for this same HistoryRecord.
4284     */
4285    private final boolean destroyActivityLocked(HistoryRecord r,
4286            boolean removeFromApp) {
4287        if (DEBUG_SWITCH) Log.v(
4288            TAG, "Removing activity: token=" + r
4289              + ", app=" + (r.app != null ? r.app.processName : "(null)"));
4290        EventLog.writeEvent(EventLogTags.AM_DESTROY_ACTIVITY,
4291                System.identityHashCode(r),
4292                r.task.taskId, r.shortComponentName);
4293
4294        boolean removedFromHistory = false;
4295
4296        cleanUpActivityLocked(r, false);
4297
4298        final boolean hadApp = r.app != null;
4299
4300        if (hadApp) {
4301            if (removeFromApp) {
4302                int idx = r.app.activities.indexOf(r);
4303                if (idx >= 0) {
4304                    r.app.activities.remove(idx);
4305                }
4306                if (r.persistent) {
4307                    decPersistentCountLocked(r.app);
4308                }
4309                if (r.app.activities.size() == 0) {
4310                    // No longer have activities, so update location in
4311                    // LRU list.
4312                    updateLruProcessLocked(r.app, true, false);
4313                }
4314            }
4315
4316            boolean skipDestroy = false;
4317
4318            try {
4319                if (DEBUG_SWITCH) Log.i(TAG, "Destroying: " + r);
4320                r.app.thread.scheduleDestroyActivity(r, r.finishing,
4321                        r.configChangeFlags);
4322            } catch (Exception e) {
4323                // We can just ignore exceptions here...  if the process
4324                // has crashed, our death notification will clean things
4325                // up.
4326                //Log.w(TAG, "Exception thrown during finish", e);
4327                if (r.finishing) {
4328                    removeActivityFromHistoryLocked(r);
4329                    removedFromHistory = true;
4330                    skipDestroy = true;
4331                }
4332            }
4333
4334            r.app = null;
4335            r.nowVisible = false;
4336
4337            if (r.finishing && !skipDestroy) {
4338                r.state = ActivityState.DESTROYING;
4339                Message msg = mHandler.obtainMessage(DESTROY_TIMEOUT_MSG);
4340                msg.obj = r;
4341                mHandler.sendMessageDelayed(msg, DESTROY_TIMEOUT);
4342            } else {
4343                r.state = ActivityState.DESTROYED;
4344            }
4345        } else {
4346            // remove this record from the history.
4347            if (r.finishing) {
4348                removeActivityFromHistoryLocked(r);
4349                removedFromHistory = true;
4350            } else {
4351                r.state = ActivityState.DESTROYED;
4352            }
4353        }
4354
4355        r.configChangeFlags = 0;
4356
4357        if (!mLRUActivities.remove(r) && hadApp) {
4358            Log.w(TAG, "Activity " + r + " being finished, but not in LRU list");
4359        }
4360
4361        return removedFromHistory;
4362    }
4363
4364    private static void removeHistoryRecordsForAppLocked(ArrayList list, ProcessRecord app) {
4365        int i = list.size();
4366        if (localLOGV) Log.v(
4367            TAG, "Removing app " + app + " from list " + list
4368            + " with " + i + " entries");
4369        while (i > 0) {
4370            i--;
4371            HistoryRecord r = (HistoryRecord)list.get(i);
4372            if (localLOGV) Log.v(
4373                TAG, "Record #" + i + " " + r + ": app=" + r.app);
4374            if (r.app == app) {
4375                if (localLOGV) Log.v(TAG, "Removing this entry!");
4376                list.remove(i);
4377            }
4378        }
4379    }
4380
4381    /**
4382     * Main function for removing an existing process from the activity manager
4383     * as a result of that process going away.  Clears out all connections
4384     * to the process.
4385     */
4386    private final void handleAppDiedLocked(ProcessRecord app,
4387            boolean restarting) {
4388        cleanUpApplicationRecordLocked(app, restarting, -1);
4389        if (!restarting) {
4390            mLruProcesses.remove(app);
4391        }
4392
4393        // Just in case...
4394        if (mPausingActivity != null && mPausingActivity.app == app) {
4395            if (DEBUG_PAUSE) Log.v(TAG, "App died while pausing: " + mPausingActivity);
4396            mPausingActivity = null;
4397        }
4398        if (mLastPausedActivity != null && mLastPausedActivity.app == app) {
4399            mLastPausedActivity = null;
4400        }
4401
4402        // Remove this application's activities from active lists.
4403        removeHistoryRecordsForAppLocked(mLRUActivities, app);
4404        removeHistoryRecordsForAppLocked(mStoppingActivities, app);
4405        removeHistoryRecordsForAppLocked(mWaitingVisibleActivities, app);
4406        removeHistoryRecordsForAppLocked(mFinishingActivities, app);
4407
4408        boolean atTop = true;
4409        boolean hasVisibleActivities = false;
4410
4411        // Clean out the history list.
4412        int i = mHistory.size();
4413        if (localLOGV) Log.v(
4414            TAG, "Removing app " + app + " from history with " + i + " entries");
4415        while (i > 0) {
4416            i--;
4417            HistoryRecord r = (HistoryRecord)mHistory.get(i);
4418            if (localLOGV) Log.v(
4419                TAG, "Record #" + i + " " + r + ": app=" + r.app);
4420            if (r.app == app) {
4421                if ((!r.haveState && !r.stateNotNeeded) || r.finishing) {
4422                    if (localLOGV) Log.v(
4423                        TAG, "Removing this entry!  frozen=" + r.haveState
4424                        + " finishing=" + r.finishing);
4425                    mHistory.remove(i);
4426
4427                    r.inHistory = false;
4428                    mWindowManager.removeAppToken(r);
4429                    if (VALIDATE_TOKENS) {
4430                        mWindowManager.validateAppTokens(mHistory);
4431                    }
4432                    removeActivityUriPermissionsLocked(r);
4433
4434                } else {
4435                    // We have the current state for this activity, so
4436                    // it can be restarted later when needed.
4437                    if (localLOGV) Log.v(
4438                        TAG, "Keeping entry, setting app to null");
4439                    if (r.visible) {
4440                        hasVisibleActivities = true;
4441                    }
4442                    r.app = null;
4443                    r.nowVisible = false;
4444                    if (!r.haveState) {
4445                        r.icicle = null;
4446                    }
4447                }
4448
4449                cleanUpActivityLocked(r, true);
4450                r.state = ActivityState.STOPPED;
4451            }
4452            atTop = false;
4453        }
4454
4455        app.activities.clear();
4456
4457        if (app.instrumentationClass != null) {
4458            Log.w(TAG, "Crash of app " + app.processName
4459                  + " running instrumentation " + app.instrumentationClass);
4460            Bundle info = new Bundle();
4461            info.putString("shortMsg", "Process crashed.");
4462            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4463        }
4464
4465        if (!restarting) {
4466            if (!resumeTopActivityLocked(null)) {
4467                // If there was nothing to resume, and we are not already
4468                // restarting this process, but there is a visible activity that
4469                // is hosted by the process...  then make sure all visible
4470                // activities are running, taking care of restarting this
4471                // process.
4472                if (hasVisibleActivities) {
4473                    ensureActivitiesVisibleLocked(null, 0);
4474                }
4475            }
4476        }
4477    }
4478
4479    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4480        IBinder threadBinder = thread.asBinder();
4481
4482        // Find the application record.
4483        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4484            ProcessRecord rec = mLruProcesses.get(i);
4485            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4486                return i;
4487            }
4488        }
4489        return -1;
4490    }
4491
4492    private final ProcessRecord getRecordForAppLocked(
4493            IApplicationThread thread) {
4494        if (thread == null) {
4495            return null;
4496        }
4497
4498        int appIndex = getLRURecordIndexForAppLocked(thread);
4499        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4500    }
4501
4502    private final void appDiedLocked(ProcessRecord app, int pid,
4503            IApplicationThread thread) {
4504
4505        mProcDeaths[0]++;
4506
4507        if (app.thread != null && app.thread.asBinder() == thread.asBinder()) {
4508            Log.i(TAG, "Process " + app.processName + " (pid " + pid
4509                    + ") has died.");
4510            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
4511            if (localLOGV) Log.v(
4512                TAG, "Dying app: " + app + ", pid: " + pid
4513                + ", thread: " + thread.asBinder());
4514            boolean doLowMem = app.instrumentationClass == null;
4515            handleAppDiedLocked(app, false);
4516
4517            if (doLowMem) {
4518                // If there are no longer any background processes running,
4519                // and the app that died was not running instrumentation,
4520                // then tell everyone we are now low on memory.
4521                boolean haveBg = false;
4522                for (int i=mLruProcesses.size()-1; i>=0; i--) {
4523                    ProcessRecord rec = mLruProcesses.get(i);
4524                    if (rec.thread != null && rec.setAdj >= HIDDEN_APP_MIN_ADJ) {
4525                        haveBg = true;
4526                        break;
4527                    }
4528                }
4529
4530                if (!haveBg) {
4531                    Log.i(TAG, "Low Memory: No more background processes.");
4532                    EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4533                    long now = SystemClock.uptimeMillis();
4534                    for (int i=mLruProcesses.size()-1; i>=0; i--) {
4535                        ProcessRecord rec = mLruProcesses.get(i);
4536                        if (rec != app && rec.thread != null &&
4537                                (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4538                            // The low memory report is overriding any current
4539                            // state for a GC request.  Make sure to do
4540                            // visible/foreground processes first.
4541                            if (rec.setAdj <= VISIBLE_APP_ADJ) {
4542                                rec.lastRequestedGc = 0;
4543                            } else {
4544                                rec.lastRequestedGc = rec.lastLowMemory;
4545                            }
4546                            rec.reportLowMemory = true;
4547                            rec.lastLowMemory = now;
4548                            mProcessesToGc.remove(rec);
4549                            addProcessToGcListLocked(rec);
4550                        }
4551                    }
4552                    scheduleAppGcsLocked();
4553                }
4554            }
4555        } else if (DEBUG_PROCESSES) {
4556            Log.d(TAG, "Received spurious death notification for thread "
4557                    + thread.asBinder());
4558        }
4559    }
4560
4561    /**
4562     * If a stack trace dump file is configured, dump process stack traces.
4563     * @param pids of dalvik VM processes to dump stack traces for
4564     * @return file containing stack traces, or null if no dump file is configured
4565     */
4566    private static File dumpStackTraces(ArrayList<Integer> pids) {
4567        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4568        if (tracesPath == null || tracesPath.length() == 0) {
4569            return null;
4570        }
4571
4572        File tracesFile = new File(tracesPath);
4573        try {
4574            File tracesDir = tracesFile.getParentFile();
4575            if (!tracesDir.exists()) tracesFile.mkdirs();
4576            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4577
4578            if (tracesFile.exists()) tracesFile.delete();
4579            tracesFile.createNewFile();
4580            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4581        } catch (IOException e) {
4582            Log.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4583            return null;
4584        }
4585
4586        // Use a FileObserver to detect when traces finish writing.
4587        // The order of traces is considered important to maintain for legibility.
4588        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4589            public synchronized void onEvent(int event, String path) { notify(); }
4590        };
4591
4592        try {
4593            observer.startWatching();
4594            int num = pids.size();
4595            for (int i = 0; i < num; i++) {
4596                synchronized (observer) {
4597                    Process.sendSignal(pids.get(i), Process.SIGNAL_QUIT);
4598                    observer.wait(200);  // Wait for write-close, give up after 200msec
4599                }
4600            }
4601        } catch (InterruptedException e) {
4602            Log.wtf(TAG, e);
4603        } finally {
4604            observer.stopWatching();
4605        }
4606
4607        return tracesFile;
4608    }
4609
4610    final void appNotRespondingLocked(ProcessRecord app, HistoryRecord activity,
4611            HistoryRecord parent, final String annotation) {
4612        if (app.notResponding || app.crashing) {
4613            return;
4614        }
4615
4616        // Log the ANR to the event log.
4617        EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags,
4618                annotation);
4619
4620        // Dump thread traces as quickly as we can, starting with "interesting" processes.
4621        ArrayList<Integer> pids = new ArrayList<Integer>(20);
4622        pids.add(app.pid);
4623
4624        int parentPid = app.pid;
4625        if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4626        if (parentPid != app.pid) pids.add(parentPid);
4627
4628        if (MY_PID != app.pid && MY_PID != parentPid) pids.add(MY_PID);
4629
4630        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4631            ProcessRecord r = mLruProcesses.get(i);
4632            if (r != null && r.thread != null) {
4633                int pid = r.pid;
4634                if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) pids.add(pid);
4635            }
4636        }
4637
4638        File tracesFile = dumpStackTraces(pids);
4639
4640        // Log the ANR to the main log.
4641        StringBuilder info = mStringBuilder;
4642        info.setLength(0);
4643        info.append("ANR in ").append(app.processName);
4644        if (activity != null && activity.shortComponentName != null) {
4645            info.append(" (").append(activity.shortComponentName).append(")");
4646        }
4647        if (annotation != null) {
4648            info.append("\nReason: ").append(annotation).append("\n");
4649        }
4650        if (parent != null && parent != activity) {
4651            info.append("\nParent: ").append(parent.shortComponentName);
4652        }
4653
4654        String cpuInfo = null;
4655        if (MONITOR_CPU_USAGE) {
4656            updateCpuStatsNow();
4657            synchronized (mProcessStatsThread) { cpuInfo = mProcessStats.printCurrentState(); }
4658            info.append(cpuInfo);
4659        }
4660
4661        Log.e(TAG, info.toString());
4662        if (tracesFile == null) {
4663            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4664            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4665        }
4666
4667        addErrorToDropBox("anr", app, activity, parent, annotation, cpuInfo, tracesFile, null);
4668
4669        if (mController != null) {
4670            try {
4671                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4672                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4673                if (res != 0) {
4674                    if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
4675                    return;
4676                }
4677            } catch (RemoteException e) {
4678                mController = null;
4679            }
4680        }
4681
4682        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4683        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4684                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4685        if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4686            Process.killProcess(app.pid);
4687            return;
4688        }
4689
4690        // Set the app's notResponding state, and look up the errorReportReceiver
4691        makeAppNotRespondingLocked(app,
4692                activity != null ? activity.shortComponentName : null,
4693                annotation != null ? "ANR " + annotation : "ANR",
4694                info.toString());
4695
4696        // Bring up the infamous App Not Responding dialog
4697        Message msg = Message.obtain();
4698        HashMap map = new HashMap();
4699        msg.what = SHOW_NOT_RESPONDING_MSG;
4700        msg.obj = map;
4701        map.put("app", app);
4702        if (activity != null) {
4703            map.put("activity", activity);
4704        }
4705
4706        mHandler.sendMessage(msg);
4707        return;
4708    }
4709
4710    private final void decPersistentCountLocked(ProcessRecord app)
4711    {
4712        app.persistentActivities--;
4713        if (app.persistentActivities > 0) {
4714            // Still more of 'em...
4715            return;
4716        }
4717        if (app.persistent) {
4718            // Ah, but the application itself is persistent.  Whatever!
4719            return;
4720        }
4721
4722        // App is no longer persistent...  make sure it and the ones
4723        // following it in the LRU list have the correc oom_adj.
4724        updateOomAdjLocked();
4725    }
4726
4727    public void setPersistent(IBinder token, boolean isPersistent) {
4728        if (checkCallingPermission(android.Manifest.permission.PERSISTENT_ACTIVITY)
4729                != PackageManager.PERMISSION_GRANTED) {
4730            String msg = "Permission Denial: setPersistent() from pid="
4731                    + Binder.getCallingPid()
4732                    + ", uid=" + Binder.getCallingUid()
4733                    + " requires " + android.Manifest.permission.PERSISTENT_ACTIVITY;
4734            Log.w(TAG, msg);
4735            throw new SecurityException(msg);
4736        }
4737
4738        synchronized(this) {
4739            int index = indexOfTokenLocked(token);
4740            if (index < 0) {
4741                return;
4742            }
4743            HistoryRecord r = (HistoryRecord)mHistory.get(index);
4744            ProcessRecord app = r.app;
4745
4746            if (localLOGV) Log.v(
4747                TAG, "Setting persistence " + isPersistent + ": " + r);
4748
4749            if (isPersistent) {
4750                if (r.persistent) {
4751                    // Okay okay, I heard you already!
4752                    if (localLOGV) Log.v(TAG, "Already persistent!");
4753                    return;
4754                }
4755                r.persistent = true;
4756                app.persistentActivities++;
4757                if (localLOGV) Log.v(TAG, "Num persistent now: " + app.persistentActivities);
4758                if (app.persistentActivities > 1) {
4759                    // We aren't the first...
4760                    if (localLOGV) Log.v(TAG, "Not the first!");
4761                    return;
4762                }
4763                if (app.persistent) {
4764                    // This would be redundant.
4765                    if (localLOGV) Log.v(TAG, "App is persistent!");
4766                    return;
4767                }
4768
4769                // App is now persistent...  make sure it and the ones
4770                // following it now have the correct oom_adj.
4771                final long origId = Binder.clearCallingIdentity();
4772                updateOomAdjLocked();
4773                Binder.restoreCallingIdentity(origId);
4774
4775            } else {
4776                if (!r.persistent) {
4777                    // Okay okay, I heard you already!
4778                    return;
4779                }
4780                r.persistent = false;
4781                final long origId = Binder.clearCallingIdentity();
4782                decPersistentCountLocked(app);
4783                Binder.restoreCallingIdentity(origId);
4784
4785            }
4786        }
4787    }
4788
4789    public boolean clearApplicationUserData(final String packageName,
4790            final IPackageDataObserver observer) {
4791        int uid = Binder.getCallingUid();
4792        int pid = Binder.getCallingPid();
4793        long callingId = Binder.clearCallingIdentity();
4794        try {
4795            IPackageManager pm = ActivityThread.getPackageManager();
4796            int pkgUid = -1;
4797            synchronized(this) {
4798                try {
4799                    pkgUid = pm.getPackageUid(packageName);
4800                } catch (RemoteException e) {
4801                }
4802                if (pkgUid == -1) {
4803                    Log.w(TAG, "Invalid packageName:" + packageName);
4804                    return false;
4805                }
4806                if (uid == pkgUid || checkComponentPermission(
4807                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4808                        pid, uid, -1)
4809                        == PackageManager.PERMISSION_GRANTED) {
4810                    forceStopPackageLocked(packageName, pkgUid);
4811                } else {
4812                    throw new SecurityException(pid+" does not have permission:"+
4813                            android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" +
4814                                    "for process:"+packageName);
4815                }
4816            }
4817
4818            try {
4819                //clear application user data
4820                pm.clearApplicationUserData(packageName, observer);
4821                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4822                        Uri.fromParts("package", packageName, null));
4823                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4824                broadcastIntentLocked(null, null, intent,
4825                        null, null, 0, null, null, null,
4826                        false, false, MY_PID, Process.SYSTEM_UID);
4827            } catch (RemoteException e) {
4828            }
4829        } finally {
4830            Binder.restoreCallingIdentity(callingId);
4831        }
4832        return true;
4833    }
4834
4835    public void killBackgroundProcesses(final String packageName) {
4836        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4837                != PackageManager.PERMISSION_GRANTED &&
4838                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4839                        != PackageManager.PERMISSION_GRANTED) {
4840            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4841                    + Binder.getCallingPid()
4842                    + ", uid=" + Binder.getCallingUid()
4843                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4844            Log.w(TAG, msg);
4845            throw new SecurityException(msg);
4846        }
4847
4848        long callingId = Binder.clearCallingIdentity();
4849        try {
4850            IPackageManager pm = ActivityThread.getPackageManager();
4851            int pkgUid = -1;
4852            synchronized(this) {
4853                try {
4854                    pkgUid = pm.getPackageUid(packageName);
4855                } catch (RemoteException e) {
4856                }
4857                if (pkgUid == -1) {
4858                    Log.w(TAG, "Invalid packageName: " + packageName);
4859                    return;
4860                }
4861                killPackageProcessesLocked(packageName, pkgUid,
4862                        SECONDARY_SERVER_ADJ, false);
4863            }
4864        } finally {
4865            Binder.restoreCallingIdentity(callingId);
4866        }
4867    }
4868
4869    public void forceStopPackage(final String packageName) {
4870        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4871                != PackageManager.PERMISSION_GRANTED) {
4872            String msg = "Permission Denial: forceStopPackage() from pid="
4873                    + Binder.getCallingPid()
4874                    + ", uid=" + Binder.getCallingUid()
4875                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4876            Log.w(TAG, msg);
4877            throw new SecurityException(msg);
4878        }
4879
4880        long callingId = Binder.clearCallingIdentity();
4881        try {
4882            IPackageManager pm = ActivityThread.getPackageManager();
4883            int pkgUid = -1;
4884            synchronized(this) {
4885                try {
4886                    pkgUid = pm.getPackageUid(packageName);
4887                } catch (RemoteException e) {
4888                }
4889                if (pkgUid == -1) {
4890                    Log.w(TAG, "Invalid packageName: " + packageName);
4891                    return;
4892                }
4893                forceStopPackageLocked(packageName, pkgUid);
4894            }
4895        } finally {
4896            Binder.restoreCallingIdentity(callingId);
4897        }
4898    }
4899
4900    /*
4901     * The pkg name and uid have to be specified.
4902     * @see android.app.IActivityManager#killApplicationWithUid(java.lang.String, int)
4903     */
4904    public void killApplicationWithUid(String pkg, int uid) {
4905        if (pkg == null) {
4906            return;
4907        }
4908        // Make sure the uid is valid.
4909        if (uid < 0) {
4910            Log.w(TAG, "Invalid uid specified for pkg : " + pkg);
4911            return;
4912        }
4913        int callerUid = Binder.getCallingUid();
4914        // Only the system server can kill an application
4915        if (callerUid == Process.SYSTEM_UID) {
4916            // Post an aysnc message to kill the application
4917            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4918            msg.arg1 = uid;
4919            msg.arg2 = 0;
4920            msg.obj = pkg;
4921            mHandler.sendMessage(msg);
4922        } else {
4923            throw new SecurityException(callerUid + " cannot kill pkg: " +
4924                    pkg);
4925        }
4926    }
4927
4928    public void closeSystemDialogs(String reason) {
4929        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4930        if (reason != null) {
4931            intent.putExtra("reason", reason);
4932        }
4933
4934        final int uid = Binder.getCallingUid();
4935        final long origId = Binder.clearCallingIdentity();
4936        synchronized (this) {
4937            int i = mWatchers.beginBroadcast();
4938            while (i > 0) {
4939                i--;
4940                IActivityWatcher w = mWatchers.getBroadcastItem(i);
4941                if (w != null) {
4942                    try {
4943                        w.closingSystemDialogs(reason);
4944                    } catch (RemoteException e) {
4945                    }
4946                }
4947            }
4948            mWatchers.finishBroadcast();
4949
4950            mWindowManager.closeSystemDialogs(reason);
4951
4952            for (i=mHistory.size()-1; i>=0; i--) {
4953                HistoryRecord r = (HistoryRecord)mHistory.get(i);
4954                if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
4955                    finishActivityLocked(r, i,
4956                            Activity.RESULT_CANCELED, null, "close-sys");
4957                }
4958            }
4959
4960            broadcastIntentLocked(null, null, intent, null,
4961                    null, 0, null, null, null, false, false, -1, uid);
4962        }
4963        Binder.restoreCallingIdentity(origId);
4964    }
4965
4966    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
4967            throws RemoteException {
4968        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4969        for (int i=pids.length-1; i>=0; i--) {
4970            infos[i] = new Debug.MemoryInfo();
4971            Debug.getMemoryInfo(pids[i], infos[i]);
4972        }
4973        return infos;
4974    }
4975
4976    public void killApplicationProcess(String processName, int uid) {
4977        if (processName == null) {
4978            return;
4979        }
4980
4981        int callerUid = Binder.getCallingUid();
4982        // Only the system server can kill an application
4983        if (callerUid == Process.SYSTEM_UID) {
4984            synchronized (this) {
4985                ProcessRecord app = getProcessRecordLocked(processName, uid);
4986                if (app != null) {
4987                    try {
4988                        app.thread.scheduleSuicide();
4989                    } catch (RemoteException e) {
4990                        // If the other end already died, then our work here is done.
4991                    }
4992                } else {
4993                    Log.w(TAG, "Process/uid not found attempting kill of "
4994                            + processName + " / " + uid);
4995                }
4996            }
4997        } else {
4998            throw new SecurityException(callerUid + " cannot kill app process: " +
4999                    processName);
5000        }
5001    }
5002
5003    private void forceStopPackageLocked(final String packageName, int uid) {
5004        forceStopPackageLocked(packageName, uid, false, false);
5005        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5006                Uri.fromParts("package", packageName, null));
5007        intent.putExtra(Intent.EXTRA_UID, uid);
5008        broadcastIntentLocked(null, null, intent,
5009                null, null, 0, null, null, null,
5010                false, false, MY_PID, Process.SYSTEM_UID);
5011    }
5012
5013    private final void killPackageProcessesLocked(String packageName, int uid,
5014            int minOomAdj, boolean callerWillRestart) {
5015        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5016
5017        // Remove all processes this package may have touched: all with the
5018        // same UID (except for the system or root user), and all whose name
5019        // matches the package name.
5020        final String procNamePrefix = packageName + ":";
5021        for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
5022            final int NA = apps.size();
5023            for (int ia=0; ia<NA; ia++) {
5024                ProcessRecord app = apps.valueAt(ia);
5025                if (app.removed) {
5026                    procs.add(app);
5027                } else if ((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid)
5028                        || app.processName.equals(packageName)
5029                        || app.processName.startsWith(procNamePrefix)) {
5030                    if (app.setAdj >= minOomAdj) {
5031                        app.removed = true;
5032                        procs.add(app);
5033                    }
5034                }
5035            }
5036        }
5037
5038        int N = procs.size();
5039        for (int i=0; i<N; i++) {
5040            removeProcessLocked(procs.get(i), callerWillRestart);
5041        }
5042    }
5043
5044    private final void forceStopPackageLocked(String name, int uid,
5045            boolean callerWillRestart, boolean purgeCache) {
5046        int i, N;
5047
5048        if (uid < 0) {
5049            try {
5050                uid = ActivityThread.getPackageManager().getPackageUid(name);
5051            } catch (RemoteException e) {
5052            }
5053        }
5054
5055        Log.i(TAG, "Force stopping package " + name + " uid=" + uid);
5056
5057        Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator();
5058        while (badApps.hasNext()) {
5059            SparseArray<Long> ba = badApps.next();
5060            if (ba.get(uid) != null) {
5061                badApps.remove();
5062            }
5063        }
5064
5065        killPackageProcessesLocked(name, uid, -100, callerWillRestart);
5066
5067        for (i=mHistory.size()-1; i>=0; i--) {
5068            HistoryRecord r = (HistoryRecord)mHistory.get(i);
5069            if (r.packageName.equals(name)) {
5070                Log.i(TAG, "  Force finishing activity " + r);
5071                if (r.app != null) {
5072                    r.app.removed = true;
5073                }
5074                r.app = null;
5075                finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "uninstall");
5076            }
5077        }
5078
5079        ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
5080        for (ServiceRecord service : mServices.values()) {
5081            if (service.packageName.equals(name)) {
5082                Log.i(TAG, "  Force stopping service " + service);
5083                if (service.app != null) {
5084                    service.app.removed = true;
5085                }
5086                service.app = null;
5087                services.add(service);
5088            }
5089        }
5090
5091        N = services.size();
5092        for (i=0; i<N; i++) {
5093            bringDownServiceLocked(services.get(i), true);
5094        }
5095
5096        resumeTopActivityLocked(null);
5097        if (purgeCache) {
5098            AttributeCache ac = AttributeCache.instance();
5099            if (ac != null) {
5100                ac.removePackage(name);
5101            }
5102        }
5103    }
5104
5105    private final boolean removeProcessLocked(ProcessRecord app, boolean callerWillRestart) {
5106        final String name = app.processName;
5107        final int uid = app.info.uid;
5108        if (DEBUG_PROCESSES) Log.d(
5109            TAG, "Force removing process " + app + " (" + name
5110            + "/" + uid + ")");
5111
5112        mProcessNames.remove(name, uid);
5113        boolean needRestart = false;
5114        if (app.pid > 0 && app.pid != MY_PID) {
5115            int pid = app.pid;
5116            synchronized (mPidsSelfLocked) {
5117                mPidsSelfLocked.remove(pid);
5118                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5119            }
5120            handleAppDiedLocked(app, true);
5121            mLruProcesses.remove(app);
5122            Process.killProcess(pid);
5123
5124            if (app.persistent) {
5125                if (!callerWillRestart) {
5126                    addAppLocked(app.info);
5127                } else {
5128                    needRestart = true;
5129                }
5130            }
5131        } else {
5132            mRemovedProcesses.add(app);
5133        }
5134
5135        return needRestart;
5136    }
5137
5138    private final void processStartTimedOutLocked(ProcessRecord app) {
5139        final int pid = app.pid;
5140        boolean gone = false;
5141        synchronized (mPidsSelfLocked) {
5142            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5143            if (knownApp != null && knownApp.thread == null) {
5144                mPidsSelfLocked.remove(pid);
5145                gone = true;
5146            }
5147        }
5148
5149        if (gone) {
5150            Log.w(TAG, "Process " + app + " failed to attach");
5151            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.info.uid,
5152                    app.processName);
5153            mProcessNames.remove(app.processName, app.info.uid);
5154            // Take care of any launching providers waiting for this process.
5155            checkAppInLaunchingProvidersLocked(app, true);
5156            // Take care of any services that are waiting for the process.
5157            for (int i=0; i<mPendingServices.size(); i++) {
5158                ServiceRecord sr = mPendingServices.get(i);
5159                if (app.info.uid == sr.appInfo.uid
5160                        && app.processName.equals(sr.processName)) {
5161                    Log.w(TAG, "Forcing bringing down service: " + sr);
5162                    mPendingServices.remove(i);
5163                    i--;
5164                    bringDownServiceLocked(sr, true);
5165                }
5166            }
5167            Process.killProcess(pid);
5168            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5169                Log.w(TAG, "Unattached app died before backup, skipping");
5170                try {
5171                    IBackupManager bm = IBackupManager.Stub.asInterface(
5172                            ServiceManager.getService(Context.BACKUP_SERVICE));
5173                    bm.agentDisconnected(app.info.packageName);
5174                } catch (RemoteException e) {
5175                    // Can't happen; the backup manager is local
5176                }
5177            }
5178            if (mPendingBroadcast != null && mPendingBroadcast.curApp.pid == pid) {
5179                Log.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5180                mPendingBroadcast = null;
5181                scheduleBroadcastsLocked();
5182            }
5183        } else {
5184            Log.w(TAG, "Spurious process start timeout - pid not known for " + app);
5185        }
5186    }
5187
5188    private final boolean attachApplicationLocked(IApplicationThread thread,
5189            int pid) {
5190
5191        // Find the application record that is being attached...  either via
5192        // the pid if we are running in multiple processes, or just pull the
5193        // next app record if we are emulating process with anonymous threads.
5194        ProcessRecord app;
5195        if (pid != MY_PID && pid >= 0) {
5196            synchronized (mPidsSelfLocked) {
5197                app = mPidsSelfLocked.get(pid);
5198            }
5199        } else if (mStartingProcesses.size() > 0) {
5200            app = mStartingProcesses.remove(0);
5201            app.setPid(pid);
5202        } else {
5203            app = null;
5204        }
5205
5206        if (app == null) {
5207            Log.w(TAG, "No pending application record for pid " + pid
5208                    + " (IApplicationThread " + thread + "); dropping process");
5209            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5210            if (pid > 0 && pid != MY_PID) {
5211                Process.killProcess(pid);
5212            } else {
5213                try {
5214                    thread.scheduleExit();
5215                } catch (Exception e) {
5216                    // Ignore exceptions.
5217                }
5218            }
5219            return false;
5220        }
5221
5222        // If this application record is still attached to a previous
5223        // process, clean it up now.
5224        if (app.thread != null) {
5225            handleAppDiedLocked(app, true);
5226        }
5227
5228        // Tell the process all about itself.
5229
5230        if (localLOGV) Log.v(
5231                TAG, "Binding process pid " + pid + " to record " + app);
5232
5233        String processName = app.processName;
5234        try {
5235            thread.asBinder().linkToDeath(new AppDeathRecipient(
5236                    app, pid, thread), 0);
5237        } catch (RemoteException e) {
5238            app.resetPackageList();
5239            startProcessLocked(app, "link fail", processName);
5240            return false;
5241        }
5242
5243        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName);
5244
5245        app.thread = thread;
5246        app.curAdj = app.setAdj = -100;
5247        app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
5248        app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
5249        app.forcingToForeground = null;
5250        app.foregroundServices = false;
5251        app.debugging = false;
5252
5253        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5254
5255        boolean normalMode = mSystemReady || isAllowedWhileBooting(app.info);
5256        List providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5257
5258        if (!normalMode) {
5259            Log.i(TAG, "Launching preboot mode app: " + app);
5260        }
5261
5262        if (localLOGV) Log.v(
5263            TAG, "New app record " + app
5264            + " thread=" + thread.asBinder() + " pid=" + pid);
5265        try {
5266            int testMode = IApplicationThread.DEBUG_OFF;
5267            if (mDebugApp != null && mDebugApp.equals(processName)) {
5268                testMode = mWaitForDebugger
5269                    ? IApplicationThread.DEBUG_WAIT
5270                    : IApplicationThread.DEBUG_ON;
5271                app.debugging = true;
5272                if (mDebugTransient) {
5273                    mDebugApp = mOrigDebugApp;
5274                    mWaitForDebugger = mOrigWaitForDebugger;
5275                }
5276            }
5277
5278            // If the app is being launched for restore or full backup, set it up specially
5279            boolean isRestrictedBackupMode = false;
5280            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5281                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5282                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5283            }
5284
5285            ensurePackageDexOpt(app.instrumentationInfo != null
5286                    ? app.instrumentationInfo.packageName
5287                    : app.info.packageName);
5288            if (app.instrumentationClass != null) {
5289                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5290            }
5291            if (DEBUG_CONFIGURATION) Log.v(TAG, "Binding proc "
5292                    + processName + " with config " + mConfiguration);
5293            thread.bindApplication(processName, app.instrumentationInfo != null
5294                    ? app.instrumentationInfo : app.info, providers,
5295                    app.instrumentationClass, app.instrumentationProfileFile,
5296                    app.instrumentationArguments, app.instrumentationWatcher, testMode,
5297                    isRestrictedBackupMode || !normalMode,
5298                    mConfiguration, getCommonServicesLocked());
5299            updateLruProcessLocked(app, false, true);
5300            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5301        } catch (Exception e) {
5302            // todo: Yikes!  What should we do?  For now we will try to
5303            // start another process, but that could easily get us in
5304            // an infinite loop of restarting processes...
5305            Log.w(TAG, "Exception thrown during bind!", e);
5306
5307            app.resetPackageList();
5308            startProcessLocked(app, "bind fail", processName);
5309            return false;
5310        }
5311
5312        // Remove this record from the list of starting applications.
5313        mPersistentStartingProcesses.remove(app);
5314        mProcessesOnHold.remove(app);
5315
5316        boolean badApp = false;
5317        boolean didSomething = false;
5318
5319        // See if the top visible activity is waiting to run in this process...
5320        HistoryRecord hr = topRunningActivityLocked(null);
5321        if (hr != null) {
5322            if (hr.app == null && app.info.uid == hr.info.applicationInfo.uid
5323                    && processName.equals(hr.processName)) {
5324                try {
5325                    if (realStartActivityLocked(hr, app, true, true)) {
5326                        didSomething = true;
5327                    }
5328                } catch (Exception e) {
5329                    Log.w(TAG, "Exception in new application when starting activity "
5330                          + hr.intent.getComponent().flattenToShortString(), e);
5331                    badApp = true;
5332                }
5333            } else {
5334                ensureActivitiesVisibleLocked(hr, null, processName, 0);
5335            }
5336        }
5337
5338        // Find any services that should be running in this process...
5339        if (!badApp && mPendingServices.size() > 0) {
5340            ServiceRecord sr = null;
5341            try {
5342                for (int i=0; i<mPendingServices.size(); i++) {
5343                    sr = mPendingServices.get(i);
5344                    if (app.info.uid != sr.appInfo.uid
5345                            || !processName.equals(sr.processName)) {
5346                        continue;
5347                    }
5348
5349                    mPendingServices.remove(i);
5350                    i--;
5351                    realStartServiceLocked(sr, app);
5352                    didSomething = true;
5353                }
5354            } catch (Exception e) {
5355                Log.w(TAG, "Exception in new application when starting service "
5356                      + sr.shortName, e);
5357                badApp = true;
5358            }
5359        }
5360
5361        // Check if the next broadcast receiver is in this process...
5362        BroadcastRecord br = mPendingBroadcast;
5363        if (!badApp && br != null && br.curApp == app) {
5364            try {
5365                mPendingBroadcast = null;
5366                processCurBroadcastLocked(br, app);
5367                didSomething = true;
5368            } catch (Exception e) {
5369                Log.w(TAG, "Exception in new application when starting receiver "
5370                      + br.curComponent.flattenToShortString(), e);
5371                badApp = true;
5372                logBroadcastReceiverDiscard(br);
5373                finishReceiverLocked(br.receiver, br.resultCode, br.resultData,
5374                        br.resultExtras, br.resultAbort, true);
5375                scheduleBroadcastsLocked();
5376            }
5377        }
5378
5379        // Check whether the next backup agent is in this process...
5380        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.info.uid) {
5381            if (DEBUG_BACKUP) Log.v(TAG, "New app is backup target, launching agent for " + app);
5382            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5383            try {
5384                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, mBackupTarget.backupMode);
5385            } catch (Exception e) {
5386                Log.w(TAG, "Exception scheduling backup agent creation: ");
5387                e.printStackTrace();
5388            }
5389        }
5390
5391        if (badApp) {
5392            // todo: Also need to kill application to deal with all
5393            // kinds of exceptions.
5394            handleAppDiedLocked(app, false);
5395            return false;
5396        }
5397
5398        if (!didSomething) {
5399            updateOomAdjLocked();
5400        }
5401
5402        return true;
5403    }
5404
5405    public final void attachApplication(IApplicationThread thread) {
5406        synchronized (this) {
5407            int callingPid = Binder.getCallingPid();
5408            final long origId = Binder.clearCallingIdentity();
5409            attachApplicationLocked(thread, callingPid);
5410            Binder.restoreCallingIdentity(origId);
5411        }
5412    }
5413
5414    public final void activityIdle(IBinder token, Configuration config) {
5415        final long origId = Binder.clearCallingIdentity();
5416        activityIdleInternal(token, false, config);
5417        Binder.restoreCallingIdentity(origId);
5418    }
5419
5420    final ArrayList<HistoryRecord> processStoppingActivitiesLocked(
5421            boolean remove) {
5422        int N = mStoppingActivities.size();
5423        if (N <= 0) return null;
5424
5425        ArrayList<HistoryRecord> stops = null;
5426
5427        final boolean nowVisible = mResumedActivity != null
5428                && mResumedActivity.nowVisible
5429                && !mResumedActivity.waitingVisible;
5430        for (int i=0; i<N; i++) {
5431            HistoryRecord s = mStoppingActivities.get(i);
5432            if (localLOGV) Log.v(TAG, "Stopping " + s + ": nowVisible="
5433                    + nowVisible + " waitingVisible=" + s.waitingVisible
5434                    + " finishing=" + s.finishing);
5435            if (s.waitingVisible && nowVisible) {
5436                mWaitingVisibleActivities.remove(s);
5437                s.waitingVisible = false;
5438                if (s.finishing) {
5439                    // If this activity is finishing, it is sitting on top of
5440                    // everyone else but we now know it is no longer needed...
5441                    // so get rid of it.  Otherwise, we need to go through the
5442                    // normal flow and hide it once we determine that it is
5443                    // hidden by the activities in front of it.
5444                    if (localLOGV) Log.v(TAG, "Before stopping, can hide: " + s);
5445                    mWindowManager.setAppVisibility(s, false);
5446                }
5447            }
5448            if (!s.waitingVisible && remove) {
5449                if (localLOGV) Log.v(TAG, "Ready to stop: " + s);
5450                if (stops == null) {
5451                    stops = new ArrayList<HistoryRecord>();
5452                }
5453                stops.add(s);
5454                mStoppingActivities.remove(i);
5455                N--;
5456                i--;
5457            }
5458        }
5459
5460        return stops;
5461    }
5462
5463    void enableScreenAfterBoot() {
5464        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5465                SystemClock.uptimeMillis());
5466        mWindowManager.enableScreenAfterBoot();
5467    }
5468
5469    final void activityIdleInternal(IBinder token, boolean fromTimeout,
5470            Configuration config) {
5471        if (localLOGV) Log.v(TAG, "Activity idle: " + token);
5472
5473        ArrayList<HistoryRecord> stops = null;
5474        ArrayList<HistoryRecord> finishes = null;
5475        ArrayList<HistoryRecord> thumbnails = null;
5476        int NS = 0;
5477        int NF = 0;
5478        int NT = 0;
5479        IApplicationThread sendThumbnail = null;
5480        boolean booting = false;
5481        boolean enableScreen = false;
5482
5483        synchronized (this) {
5484            if (token != null) {
5485                mHandler.removeMessages(IDLE_TIMEOUT_MSG, token);
5486            }
5487
5488            // Get the activity record.
5489            int index = indexOfTokenLocked(token);
5490            if (index >= 0) {
5491                HistoryRecord r = (HistoryRecord)mHistory.get(index);
5492
5493                // This is a hack to semi-deal with a race condition
5494                // in the client where it can be constructed with a
5495                // newer configuration from when we asked it to launch.
5496                // We'll update with whatever configuration it now says
5497                // it used to launch.
5498                if (config != null) {
5499                    r.configuration = config;
5500                }
5501
5502                // No longer need to keep the device awake.
5503                if (mResumedActivity == r && mLaunchingActivity.isHeld()) {
5504                    mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
5505                    mLaunchingActivity.release();
5506                }
5507
5508                // We are now idle.  If someone is waiting for a thumbnail from
5509                // us, we can now deliver.
5510                r.idle = true;
5511                scheduleAppGcsLocked();
5512                if (r.thumbnailNeeded && r.app != null && r.app.thread != null) {
5513                    sendThumbnail = r.app.thread;
5514                    r.thumbnailNeeded = false;
5515                }
5516
5517                // If this activity is fullscreen, set up to hide those under it.
5518
5519                if (DEBUG_VISBILITY) Log.v(TAG, "Idle activity for " + r);
5520                ensureActivitiesVisibleLocked(null, 0);
5521
5522                //Log.i(TAG, "IDLE: mBooted=" + mBooted + ", fromTimeout=" + fromTimeout);
5523                if (!mBooted && !fromTimeout) {
5524                    mBooted = true;
5525                    enableScreen = true;
5526                }
5527            }
5528
5529            // Atomically retrieve all of the other things to do.
5530            stops = processStoppingActivitiesLocked(true);
5531            NS = stops != null ? stops.size() : 0;
5532            if ((NF=mFinishingActivities.size()) > 0) {
5533                finishes = new ArrayList<HistoryRecord>(mFinishingActivities);
5534                mFinishingActivities.clear();
5535            }
5536            if ((NT=mCancelledThumbnails.size()) > 0) {
5537                thumbnails = new ArrayList<HistoryRecord>(mCancelledThumbnails);
5538                mCancelledThumbnails.clear();
5539            }
5540
5541            booting = mBooting;
5542            mBooting = false;
5543        }
5544
5545        int i;
5546
5547        // Send thumbnail if requested.
5548        if (sendThumbnail != null) {
5549            try {
5550                sendThumbnail.requestThumbnail(token);
5551            } catch (Exception e) {
5552                Log.w(TAG, "Exception thrown when requesting thumbnail", e);
5553                sendPendingThumbnail(null, token, null, null, true);
5554            }
5555        }
5556
5557        // Stop any activities that are scheduled to do so but have been
5558        // waiting for the next one to start.
5559        for (i=0; i<NS; i++) {
5560            HistoryRecord r = (HistoryRecord)stops.get(i);
5561            synchronized (this) {
5562                if (r.finishing) {
5563                    finishCurrentActivityLocked(r, FINISH_IMMEDIATELY);
5564                } else {
5565                    stopActivityLocked(r);
5566                }
5567            }
5568        }
5569
5570        // Finish any activities that are scheduled to do so but have been
5571        // waiting for the next one to start.
5572        for (i=0; i<NF; i++) {
5573            HistoryRecord r = (HistoryRecord)finishes.get(i);
5574            synchronized (this) {
5575                destroyActivityLocked(r, true);
5576            }
5577        }
5578
5579        // Report back to any thumbnail receivers.
5580        for (i=0; i<NT; i++) {
5581            HistoryRecord r = (HistoryRecord)thumbnails.get(i);
5582            sendPendingThumbnail(r, null, null, null, true);
5583        }
5584
5585        if (booting) {
5586            finishBooting();
5587        }
5588
5589        trimApplications();
5590        //dump();
5591        //mWindowManager.dump();
5592
5593        if (enableScreen) {
5594            enableScreenAfterBoot();
5595        }
5596    }
5597
5598    final void finishBooting() {
5599        // Ensure that any processes we had put on hold are now started
5600        // up.
5601        final int NP = mProcessesOnHold.size();
5602        if (NP > 0) {
5603            ArrayList<ProcessRecord> procs =
5604                new ArrayList<ProcessRecord>(mProcessesOnHold);
5605            for (int ip=0; ip<NP; ip++) {
5606                this.startProcessLocked(procs.get(ip), "on-hold", null);
5607            }
5608        }
5609        if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
5610            // Tell anyone interested that we are done booting!
5611            synchronized (this) {
5612                broadcastIntentLocked(null, null,
5613                        new Intent(Intent.ACTION_BOOT_COMPLETED, null),
5614                        null, null, 0, null, null,
5615                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5616                        false, false, MY_PID, Process.SYSTEM_UID);
5617            }
5618        }
5619    }
5620
5621    final void ensureBootCompleted() {
5622        boolean booting;
5623        boolean enableScreen;
5624        synchronized (this) {
5625            booting = mBooting;
5626            mBooting = false;
5627            enableScreen = !mBooted;
5628            mBooted = true;
5629        }
5630
5631        if (booting) {
5632            finishBooting();
5633        }
5634
5635        if (enableScreen) {
5636            enableScreenAfterBoot();
5637        }
5638    }
5639
5640    public final void activityPaused(IBinder token, Bundle icicle) {
5641        // Refuse possible leaked file descriptors
5642        if (icicle != null && icicle.hasFileDescriptors()) {
5643            throw new IllegalArgumentException("File descriptors passed in Bundle");
5644        }
5645
5646        final long origId = Binder.clearCallingIdentity();
5647        activityPaused(token, icicle, false);
5648        Binder.restoreCallingIdentity(origId);
5649    }
5650
5651    final void activityPaused(IBinder token, Bundle icicle, boolean timeout) {
5652        if (DEBUG_PAUSE) Log.v(
5653            TAG, "Activity paused: token=" + token + ", icicle=" + icicle
5654            + ", timeout=" + timeout);
5655
5656        HistoryRecord r = null;
5657
5658        synchronized (this) {
5659            int index = indexOfTokenLocked(token);
5660            if (index >= 0) {
5661                r = (HistoryRecord)mHistory.get(index);
5662                if (!timeout) {
5663                    r.icicle = icicle;
5664                    r.haveState = true;
5665                }
5666                mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);
5667                if (mPausingActivity == r) {
5668                    r.state = ActivityState.PAUSED;
5669                    completePauseLocked();
5670                } else {
5671                	EventLog.writeEvent(EventLogTags.AM_FAILED_TO_PAUSE,
5672                	        System.identityHashCode(r), r.shortComponentName,
5673                			mPausingActivity != null
5674                			    ? mPausingActivity.shortComponentName : "(none)");
5675                }
5676            }
5677        }
5678    }
5679
5680    public final void activityStopped(IBinder token, Bitmap thumbnail,
5681            CharSequence description) {
5682        if (localLOGV) Log.v(
5683            TAG, "Activity stopped: token=" + token);
5684
5685        HistoryRecord r = null;
5686
5687        final long origId = Binder.clearCallingIdentity();
5688
5689        synchronized (this) {
5690            int index = indexOfTokenLocked(token);
5691            if (index >= 0) {
5692                r = (HistoryRecord)mHistory.get(index);
5693                r.thumbnail = thumbnail;
5694                r.description = description;
5695                r.stopped = true;
5696                r.state = ActivityState.STOPPED;
5697                if (!r.finishing) {
5698                    if (r.configDestroy) {
5699                        destroyActivityLocked(r, true);
5700                        resumeTopActivityLocked(null);
5701                    }
5702                }
5703            }
5704        }
5705
5706        if (r != null) {
5707            sendPendingThumbnail(r, null, null, null, false);
5708        }
5709
5710        trimApplications();
5711
5712        Binder.restoreCallingIdentity(origId);
5713    }
5714
5715    public final void activityDestroyed(IBinder token) {
5716        if (DEBUG_SWITCH) Log.v(TAG, "ACTIVITY DESTROYED: " + token);
5717        synchronized (this) {
5718            mHandler.removeMessages(DESTROY_TIMEOUT_MSG, token);
5719
5720            int index = indexOfTokenLocked(token);
5721            if (index >= 0) {
5722                HistoryRecord r = (HistoryRecord)mHistory.get(index);
5723                if (r.state == ActivityState.DESTROYING) {
5724                    final long origId = Binder.clearCallingIdentity();
5725                    removeActivityFromHistoryLocked(r);
5726                    Binder.restoreCallingIdentity(origId);
5727                }
5728            }
5729        }
5730    }
5731
5732    public String getCallingPackage(IBinder token) {
5733        synchronized (this) {
5734            HistoryRecord r = getCallingRecordLocked(token);
5735            return r != null && r.app != null ? r.info.packageName : null;
5736        }
5737    }
5738
5739    public ComponentName getCallingActivity(IBinder token) {
5740        synchronized (this) {
5741            HistoryRecord r = getCallingRecordLocked(token);
5742            return r != null ? r.intent.getComponent() : null;
5743        }
5744    }
5745
5746    private HistoryRecord getCallingRecordLocked(IBinder token) {
5747        int index = indexOfTokenLocked(token);
5748        if (index >= 0) {
5749            HistoryRecord r = (HistoryRecord)mHistory.get(index);
5750            if (r != null) {
5751                return r.resultTo;
5752            }
5753        }
5754        return null;
5755    }
5756
5757    public ComponentName getActivityClassForToken(IBinder token) {
5758        synchronized(this) {
5759            int index = indexOfTokenLocked(token);
5760            if (index >= 0) {
5761                HistoryRecord r = (HistoryRecord)mHistory.get(index);
5762                return r.intent.getComponent();
5763            }
5764            return null;
5765        }
5766    }
5767
5768    public String getPackageForToken(IBinder token) {
5769        synchronized(this) {
5770            int index = indexOfTokenLocked(token);
5771            if (index >= 0) {
5772                HistoryRecord r = (HistoryRecord)mHistory.get(index);
5773                return r.packageName;
5774            }
5775            return null;
5776        }
5777    }
5778
5779    public IIntentSender getIntentSender(int type,
5780            String packageName, IBinder token, String resultWho,
5781            int requestCode, Intent intent, String resolvedType, int flags) {
5782        // Refuse possible leaked file descriptors
5783        if (intent != null && intent.hasFileDescriptors() == true) {
5784            throw new IllegalArgumentException("File descriptors passed in Intent");
5785        }
5786
5787        if (type == INTENT_SENDER_BROADCAST) {
5788            if ((intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5789                throw new IllegalArgumentException(
5790                        "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5791            }
5792        }
5793
5794        synchronized(this) {
5795            int callingUid = Binder.getCallingUid();
5796            try {
5797                if (callingUid != 0 && callingUid != Process.SYSTEM_UID &&
5798                        Process.supportsProcesses()) {
5799                    int uid = ActivityThread.getPackageManager()
5800                            .getPackageUid(packageName);
5801                    if (uid != Binder.getCallingUid()) {
5802                        String msg = "Permission Denial: getIntentSender() from pid="
5803                            + Binder.getCallingPid()
5804                            + ", uid=" + Binder.getCallingUid()
5805                            + ", (need uid=" + uid + ")"
5806                            + " is not allowed to send as package " + packageName;
5807                        Log.w(TAG, msg);
5808                        throw new SecurityException(msg);
5809                    }
5810                }
5811            } catch (RemoteException e) {
5812                throw new SecurityException(e);
5813            }
5814            HistoryRecord activity = null;
5815            if (type == INTENT_SENDER_ACTIVITY_RESULT) {
5816                int index = indexOfTokenLocked(token);
5817                if (index < 0) {
5818                    return null;
5819                }
5820                activity = (HistoryRecord)mHistory.get(index);
5821                if (activity.finishing) {
5822                    return null;
5823                }
5824            }
5825
5826            final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5827            final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5828            final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5829            flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5830                    |PendingIntent.FLAG_UPDATE_CURRENT);
5831
5832            PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5833                    type, packageName, activity, resultWho,
5834                    requestCode, intent, resolvedType, flags);
5835            WeakReference<PendingIntentRecord> ref;
5836            ref = mIntentSenderRecords.get(key);
5837            PendingIntentRecord rec = ref != null ? ref.get() : null;
5838            if (rec != null) {
5839                if (!cancelCurrent) {
5840                    if (updateCurrent) {
5841                        rec.key.requestIntent.replaceExtras(intent);
5842                    }
5843                    return rec;
5844                }
5845                rec.canceled = true;
5846                mIntentSenderRecords.remove(key);
5847            }
5848            if (noCreate) {
5849                return rec;
5850            }
5851            rec = new PendingIntentRecord(this, key, callingUid);
5852            mIntentSenderRecords.put(key, rec.ref);
5853            if (type == INTENT_SENDER_ACTIVITY_RESULT) {
5854                if (activity.pendingResults == null) {
5855                    activity.pendingResults
5856                            = new HashSet<WeakReference<PendingIntentRecord>>();
5857                }
5858                activity.pendingResults.add(rec.ref);
5859            }
5860            return rec;
5861        }
5862    }
5863
5864    public void cancelIntentSender(IIntentSender sender) {
5865        if (!(sender instanceof PendingIntentRecord)) {
5866            return;
5867        }
5868        synchronized(this) {
5869            PendingIntentRecord rec = (PendingIntentRecord)sender;
5870            try {
5871                int uid = ActivityThread.getPackageManager()
5872                        .getPackageUid(rec.key.packageName);
5873                if (uid != Binder.getCallingUid()) {
5874                    String msg = "Permission Denial: cancelIntentSender() from pid="
5875                        + Binder.getCallingPid()
5876                        + ", uid=" + Binder.getCallingUid()
5877                        + " is not allowed to cancel packges "
5878                        + rec.key.packageName;
5879                    Log.w(TAG, msg);
5880                    throw new SecurityException(msg);
5881                }
5882            } catch (RemoteException e) {
5883                throw new SecurityException(e);
5884            }
5885            cancelIntentSenderLocked(rec, true);
5886        }
5887    }
5888
5889    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5890        rec.canceled = true;
5891        mIntentSenderRecords.remove(rec.key);
5892        if (cleanActivity && rec.key.activity != null) {
5893            rec.key.activity.pendingResults.remove(rec.ref);
5894        }
5895    }
5896
5897    public String getPackageForIntentSender(IIntentSender pendingResult) {
5898        if (!(pendingResult instanceof PendingIntentRecord)) {
5899            return null;
5900        }
5901        synchronized(this) {
5902            try {
5903                PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5904                return res.key.packageName;
5905            } catch (ClassCastException e) {
5906            }
5907        }
5908        return null;
5909    }
5910
5911    public void setProcessLimit(int max) {
5912        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5913                "setProcessLimit()");
5914        mProcessLimit = max;
5915    }
5916
5917    public int getProcessLimit() {
5918        return mProcessLimit;
5919    }
5920
5921    void foregroundTokenDied(ForegroundToken token) {
5922        synchronized (ActivityManagerService.this) {
5923            synchronized (mPidsSelfLocked) {
5924                ForegroundToken cur
5925                    = mForegroundProcesses.get(token.pid);
5926                if (cur != token) {
5927                    return;
5928                }
5929                mForegroundProcesses.remove(token.pid);
5930                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
5931                if (pr == null) {
5932                    return;
5933                }
5934                pr.forcingToForeground = null;
5935                pr.foregroundServices = false;
5936            }
5937            updateOomAdjLocked();
5938        }
5939    }
5940
5941    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
5942        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5943                "setProcessForeground()");
5944        synchronized(this) {
5945            boolean changed = false;
5946
5947            synchronized (mPidsSelfLocked) {
5948                ProcessRecord pr = mPidsSelfLocked.get(pid);
5949                if (pr == null) {
5950                    Log.w(TAG, "setProcessForeground called on unknown pid: " + pid);
5951                    return;
5952                }
5953                ForegroundToken oldToken = mForegroundProcesses.get(pid);
5954                if (oldToken != null) {
5955                    oldToken.token.unlinkToDeath(oldToken, 0);
5956                    mForegroundProcesses.remove(pid);
5957                    pr.forcingToForeground = null;
5958                    changed = true;
5959                }
5960                if (isForeground && token != null) {
5961                    ForegroundToken newToken = new ForegroundToken() {
5962                        public void binderDied() {
5963                            foregroundTokenDied(this);
5964                        }
5965                    };
5966                    newToken.pid = pid;
5967                    newToken.token = token;
5968                    try {
5969                        token.linkToDeath(newToken, 0);
5970                        mForegroundProcesses.put(pid, newToken);
5971                        pr.forcingToForeground = token;
5972                        changed = true;
5973                    } catch (RemoteException e) {
5974                        // If the process died while doing this, we will later
5975                        // do the cleanup with the process death link.
5976                    }
5977                }
5978            }
5979
5980            if (changed) {
5981                updateOomAdjLocked();
5982            }
5983        }
5984    }
5985
5986    // =========================================================
5987    // PERMISSIONS
5988    // =========================================================
5989
5990    static class PermissionController extends IPermissionController.Stub {
5991        ActivityManagerService mActivityManagerService;
5992        PermissionController(ActivityManagerService activityManagerService) {
5993            mActivityManagerService = activityManagerService;
5994        }
5995
5996        public boolean checkPermission(String permission, int pid, int uid) {
5997            return mActivityManagerService.checkPermission(permission, pid,
5998                    uid) == PackageManager.PERMISSION_GRANTED;
5999        }
6000    }
6001
6002    /**
6003     * This can be called with or without the global lock held.
6004     */
6005    int checkComponentPermission(String permission, int pid, int uid,
6006            int reqUid) {
6007        // We might be performing an operation on behalf of an indirect binder
6008        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6009        // client identity accordingly before proceeding.
6010        Identity tlsIdentity = sCallerIdentity.get();
6011        if (tlsIdentity != null) {
6012            Log.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6013                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6014            uid = tlsIdentity.uid;
6015            pid = tlsIdentity.pid;
6016        }
6017
6018        // Root, system server and our own process get to do everything.
6019        if (uid == 0 || uid == Process.SYSTEM_UID || pid == MY_PID ||
6020            !Process.supportsProcesses()) {
6021            return PackageManager.PERMISSION_GRANTED;
6022        }
6023        // If the target requires a specific UID, always fail for others.
6024        if (reqUid >= 0 && uid != reqUid) {
6025            Log.w(TAG, "Permission denied: checkComponentPermission() reqUid=" + reqUid);
6026            return PackageManager.PERMISSION_DENIED;
6027        }
6028        if (permission == null) {
6029            return PackageManager.PERMISSION_GRANTED;
6030        }
6031        try {
6032            return ActivityThread.getPackageManager()
6033                    .checkUidPermission(permission, uid);
6034        } catch (RemoteException e) {
6035            // Should never happen, but if it does... deny!
6036            Log.e(TAG, "PackageManager is dead?!?", e);
6037        }
6038        return PackageManager.PERMISSION_DENIED;
6039    }
6040
6041    /**
6042     * As the only public entry point for permissions checking, this method
6043     * can enforce the semantic that requesting a check on a null global
6044     * permission is automatically denied.  (Internally a null permission
6045     * string is used when calling {@link #checkComponentPermission} in cases
6046     * when only uid-based security is needed.)
6047     *
6048     * This can be called with or without the global lock held.
6049     */
6050    public int checkPermission(String permission, int pid, int uid) {
6051        if (permission == null) {
6052            return PackageManager.PERMISSION_DENIED;
6053        }
6054        return checkComponentPermission(permission, pid, uid, -1);
6055    }
6056
6057    /**
6058     * Binder IPC calls go through the public entry point.
6059     * This can be called with or without the global lock held.
6060     */
6061    int checkCallingPermission(String permission) {
6062        return checkPermission(permission,
6063                Binder.getCallingPid(),
6064                Binder.getCallingUid());
6065    }
6066
6067    /**
6068     * This can be called with or without the global lock held.
6069     */
6070    void enforceCallingPermission(String permission, String func) {
6071        if (checkCallingPermission(permission)
6072                == PackageManager.PERMISSION_GRANTED) {
6073            return;
6074        }
6075
6076        String msg = "Permission Denial: " + func + " from pid="
6077                + Binder.getCallingPid()
6078                + ", uid=" + Binder.getCallingUid()
6079                + " requires " + permission;
6080        Log.w(TAG, msg);
6081        throw new SecurityException(msg);
6082    }
6083
6084    private final boolean checkHoldingPermissionsLocked(IPackageManager pm,
6085            ProviderInfo pi, int uid, int modeFlags) {
6086        try {
6087            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6088                if ((pi.readPermission != null) &&
6089                        (pm.checkUidPermission(pi.readPermission, uid)
6090                                != PackageManager.PERMISSION_GRANTED)) {
6091                    return false;
6092                }
6093            }
6094            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6095                if ((pi.writePermission != null) &&
6096                        (pm.checkUidPermission(pi.writePermission, uid)
6097                                != PackageManager.PERMISSION_GRANTED)) {
6098                    return false;
6099                }
6100            }
6101            return true;
6102        } catch (RemoteException e) {
6103            return false;
6104        }
6105    }
6106
6107    private final boolean checkUriPermissionLocked(Uri uri, int uid,
6108            int modeFlags) {
6109        // Root gets to do everything.
6110        if (uid == 0 || !Process.supportsProcesses()) {
6111            return true;
6112        }
6113        HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6114        if (perms == null) return false;
6115        UriPermission perm = perms.get(uri);
6116        if (perm == null) return false;
6117        return (modeFlags&perm.modeFlags) == modeFlags;
6118    }
6119
6120    public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
6121        // Another redirected-binder-call permissions check as in
6122        // {@link checkComponentPermission}.
6123        Identity tlsIdentity = sCallerIdentity.get();
6124        if (tlsIdentity != null) {
6125            uid = tlsIdentity.uid;
6126            pid = tlsIdentity.pid;
6127        }
6128
6129        // Our own process gets to do everything.
6130        if (pid == MY_PID) {
6131            return PackageManager.PERMISSION_GRANTED;
6132        }
6133        synchronized(this) {
6134            return checkUriPermissionLocked(uri, uid, modeFlags)
6135                    ? PackageManager.PERMISSION_GRANTED
6136                    : PackageManager.PERMISSION_DENIED;
6137        }
6138    }
6139
6140    private void grantUriPermissionLocked(int callingUid,
6141            String targetPkg, Uri uri, int modeFlags, HistoryRecord activity) {
6142        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
6143                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6144        if (modeFlags == 0) {
6145            return;
6146        }
6147
6148        final IPackageManager pm = ActivityThread.getPackageManager();
6149
6150        // If this is not a content: uri, we can't do anything with it.
6151        if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
6152            return;
6153        }
6154
6155        String name = uri.getAuthority();
6156        ProviderInfo pi = null;
6157        ContentProviderRecord cpr
6158                = (ContentProviderRecord)mProvidersByName.get(name);
6159        if (cpr != null) {
6160            pi = cpr.info;
6161        } else {
6162            try {
6163                pi = pm.resolveContentProvider(name,
6164                        PackageManager.GET_URI_PERMISSION_PATTERNS);
6165            } catch (RemoteException ex) {
6166            }
6167        }
6168        if (pi == null) {
6169            Log.w(TAG, "No content provider found for: " + name);
6170            return;
6171        }
6172
6173        int targetUid;
6174        try {
6175            targetUid = pm.getPackageUid(targetPkg);
6176            if (targetUid < 0) {
6177                return;
6178            }
6179        } catch (RemoteException ex) {
6180            return;
6181        }
6182
6183        // First...  does the target actually need this permission?
6184        if (checkHoldingPermissionsLocked(pm, pi, targetUid, modeFlags)) {
6185            // No need to grant the target this permission.
6186            return;
6187        }
6188
6189        // Second...  maybe someone else has already granted the
6190        // permission?
6191        if (checkUriPermissionLocked(uri, targetUid, modeFlags)) {
6192            // No need to grant the target this permission.
6193            return;
6194        }
6195
6196        // Third...  is the provider allowing granting of URI permissions?
6197        if (!pi.grantUriPermissions) {
6198            throw new SecurityException("Provider " + pi.packageName
6199                    + "/" + pi.name
6200                    + " does not allow granting of Uri permissions (uri "
6201                    + uri + ")");
6202        }
6203        if (pi.uriPermissionPatterns != null) {
6204            final int N = pi.uriPermissionPatterns.length;
6205            boolean allowed = false;
6206            for (int i=0; i<N; i++) {
6207                if (pi.uriPermissionPatterns[i] != null
6208                        && pi.uriPermissionPatterns[i].match(uri.getPath())) {
6209                    allowed = true;
6210                    break;
6211                }
6212            }
6213            if (!allowed) {
6214                throw new SecurityException("Provider " + pi.packageName
6215                        + "/" + pi.name
6216                        + " does not allow granting of permission to path of Uri "
6217                        + uri);
6218            }
6219        }
6220
6221        // Fourth...  does the caller itself have permission to access
6222        // this uri?
6223        if (!checkHoldingPermissionsLocked(pm, pi, callingUid, modeFlags)) {
6224            if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6225                throw new SecurityException("Uid " + callingUid
6226                        + " does not have permission to uri " + uri);
6227            }
6228        }
6229
6230        // Okay!  So here we are: the caller has the assumed permission
6231        // to the uri, and the target doesn't.  Let's now give this to
6232        // the target.
6233
6234        HashMap<Uri, UriPermission> targetUris
6235                = mGrantedUriPermissions.get(targetUid);
6236        if (targetUris == null) {
6237            targetUris = new HashMap<Uri, UriPermission>();
6238            mGrantedUriPermissions.put(targetUid, targetUris);
6239        }
6240
6241        UriPermission perm = targetUris.get(uri);
6242        if (perm == null) {
6243            perm = new UriPermission(targetUid, uri);
6244            targetUris.put(uri, perm);
6245
6246        }
6247        perm.modeFlags |= modeFlags;
6248        if (activity == null) {
6249            perm.globalModeFlags |= modeFlags;
6250        } else if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6251            perm.readActivities.add(activity);
6252            if (activity.readUriPermissions == null) {
6253                activity.readUriPermissions = new HashSet<UriPermission>();
6254            }
6255            activity.readUriPermissions.add(perm);
6256        } else if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6257            perm.writeActivities.add(activity);
6258            if (activity.writeUriPermissions == null) {
6259                activity.writeUriPermissions = new HashSet<UriPermission>();
6260            }
6261            activity.writeUriPermissions.add(perm);
6262        }
6263    }
6264
6265    private void grantUriPermissionFromIntentLocked(int callingUid,
6266            String targetPkg, Intent intent, HistoryRecord activity) {
6267        if (intent == null) {
6268            return;
6269        }
6270        Uri data = intent.getData();
6271        if (data == null) {
6272            return;
6273        }
6274        grantUriPermissionLocked(callingUid, targetPkg, data,
6275                intent.getFlags(), activity);
6276    }
6277
6278    public void grantUriPermission(IApplicationThread caller, String targetPkg,
6279            Uri uri, int modeFlags) {
6280        synchronized(this) {
6281            final ProcessRecord r = getRecordForAppLocked(caller);
6282            if (r == null) {
6283                throw new SecurityException("Unable to find app for caller "
6284                        + caller
6285                        + " when granting permission to uri " + uri);
6286            }
6287            if (targetPkg == null) {
6288                Log.w(TAG, "grantUriPermission: null target");
6289                return;
6290            }
6291            if (uri == null) {
6292                Log.w(TAG, "grantUriPermission: null uri");
6293                return;
6294            }
6295
6296            grantUriPermissionLocked(r.info.uid, targetPkg, uri, modeFlags,
6297                    null);
6298        }
6299    }
6300
6301    private void removeUriPermissionIfNeededLocked(UriPermission perm) {
6302        if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
6303                |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
6304            HashMap<Uri, UriPermission> perms
6305                    = mGrantedUriPermissions.get(perm.uid);
6306            if (perms != null) {
6307                perms.remove(perm.uri);
6308                if (perms.size() == 0) {
6309                    mGrantedUriPermissions.remove(perm.uid);
6310                }
6311            }
6312        }
6313    }
6314
6315    private void removeActivityUriPermissionsLocked(HistoryRecord activity) {
6316        if (activity.readUriPermissions != null) {
6317            for (UriPermission perm : activity.readUriPermissions) {
6318                perm.readActivities.remove(activity);
6319                if (perm.readActivities.size() == 0 && (perm.globalModeFlags
6320                        &Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0) {
6321                    perm.modeFlags &= ~Intent.FLAG_GRANT_READ_URI_PERMISSION;
6322                    removeUriPermissionIfNeededLocked(perm);
6323                }
6324            }
6325        }
6326        if (activity.writeUriPermissions != null) {
6327            for (UriPermission perm : activity.writeUriPermissions) {
6328                perm.writeActivities.remove(activity);
6329                if (perm.writeActivities.size() == 0 && (perm.globalModeFlags
6330                        &Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0) {
6331                    perm.modeFlags &= ~Intent.FLAG_GRANT_WRITE_URI_PERMISSION;
6332                    removeUriPermissionIfNeededLocked(perm);
6333                }
6334            }
6335        }
6336    }
6337
6338    private void revokeUriPermissionLocked(int callingUid, Uri uri,
6339            int modeFlags) {
6340        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
6341                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6342        if (modeFlags == 0) {
6343            return;
6344        }
6345
6346        final IPackageManager pm = ActivityThread.getPackageManager();
6347
6348        final String authority = uri.getAuthority();
6349        ProviderInfo pi = null;
6350        ContentProviderRecord cpr
6351                = (ContentProviderRecord)mProvidersByName.get(authority);
6352        if (cpr != null) {
6353            pi = cpr.info;
6354        } else {
6355            try {
6356                pi = pm.resolveContentProvider(authority,
6357                        PackageManager.GET_URI_PERMISSION_PATTERNS);
6358            } catch (RemoteException ex) {
6359            }
6360        }
6361        if (pi == null) {
6362            Log.w(TAG, "No content provider found for: " + authority);
6363            return;
6364        }
6365
6366        // Does the caller have this permission on the URI?
6367        if (!checkHoldingPermissionsLocked(pm, pi, callingUid, modeFlags)) {
6368            // Right now, if you are not the original owner of the permission,
6369            // you are not allowed to revoke it.
6370            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6371                throw new SecurityException("Uid " + callingUid
6372                        + " does not have permission to uri " + uri);
6373            //}
6374        }
6375
6376        // Go through all of the permissions and remove any that match.
6377        final List<String> SEGMENTS = uri.getPathSegments();
6378        if (SEGMENTS != null) {
6379            final int NS = SEGMENTS.size();
6380            int N = mGrantedUriPermissions.size();
6381            for (int i=0; i<N; i++) {
6382                HashMap<Uri, UriPermission> perms
6383                        = mGrantedUriPermissions.valueAt(i);
6384                Iterator<UriPermission> it = perms.values().iterator();
6385            toploop:
6386                while (it.hasNext()) {
6387                    UriPermission perm = it.next();
6388                    Uri targetUri = perm.uri;
6389                    if (!authority.equals(targetUri.getAuthority())) {
6390                        continue;
6391                    }
6392                    List<String> targetSegments = targetUri.getPathSegments();
6393                    if (targetSegments == null) {
6394                        continue;
6395                    }
6396                    if (targetSegments.size() < NS) {
6397                        continue;
6398                    }
6399                    for (int j=0; j<NS; j++) {
6400                        if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
6401                            continue toploop;
6402                        }
6403                    }
6404                    perm.clearModes(modeFlags);
6405                    if (perm.modeFlags == 0) {
6406                        it.remove();
6407                    }
6408                }
6409                if (perms.size() == 0) {
6410                    mGrantedUriPermissions.remove(
6411                            mGrantedUriPermissions.keyAt(i));
6412                    N--;
6413                    i--;
6414                }
6415            }
6416        }
6417    }
6418
6419    public void revokeUriPermission(IApplicationThread caller, Uri uri,
6420            int modeFlags) {
6421        synchronized(this) {
6422            final ProcessRecord r = getRecordForAppLocked(caller);
6423            if (r == null) {
6424                throw new SecurityException("Unable to find app for caller "
6425                        + caller
6426                        + " when revoking permission to uri " + uri);
6427            }
6428            if (uri == null) {
6429                Log.w(TAG, "revokeUriPermission: null uri");
6430                return;
6431            }
6432
6433            modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
6434                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6435            if (modeFlags == 0) {
6436                return;
6437            }
6438
6439            final IPackageManager pm = ActivityThread.getPackageManager();
6440
6441            final String authority = uri.getAuthority();
6442            ProviderInfo pi = null;
6443            ContentProviderRecord cpr
6444                    = (ContentProviderRecord)mProvidersByName.get(authority);
6445            if (cpr != null) {
6446                pi = cpr.info;
6447            } else {
6448                try {
6449                    pi = pm.resolveContentProvider(authority,
6450                            PackageManager.GET_URI_PERMISSION_PATTERNS);
6451                } catch (RemoteException ex) {
6452                }
6453            }
6454            if (pi == null) {
6455                Log.w(TAG, "No content provider found for: " + authority);
6456                return;
6457            }
6458
6459            revokeUriPermissionLocked(r.info.uid, uri, modeFlags);
6460        }
6461    }
6462
6463    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
6464        synchronized (this) {
6465            ProcessRecord app =
6466                who != null ? getRecordForAppLocked(who) : null;
6467            if (app == null) return;
6468
6469            Message msg = Message.obtain();
6470            msg.what = WAIT_FOR_DEBUGGER_MSG;
6471            msg.obj = app;
6472            msg.arg1 = waiting ? 1 : 0;
6473            mHandler.sendMessage(msg);
6474        }
6475    }
6476
6477    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
6478        outInfo.availMem = Process.getFreeMemory();
6479        outInfo.threshold = HOME_APP_MEM;
6480        outInfo.lowMemory = outInfo.availMem <
6481                (HOME_APP_MEM + ((HIDDEN_APP_MEM-HOME_APP_MEM)/2));
6482    }
6483
6484    // =========================================================
6485    // TASK MANAGEMENT
6486    // =========================================================
6487
6488    public List getTasks(int maxNum, int flags,
6489                         IThumbnailReceiver receiver) {
6490        ArrayList list = new ArrayList();
6491
6492        PendingThumbnailsRecord pending = null;
6493        IApplicationThread topThumbnail = null;
6494        HistoryRecord topRecord = null;
6495
6496        synchronized(this) {
6497            if (localLOGV) Log.v(
6498                TAG, "getTasks: max=" + maxNum + ", flags=" + flags
6499                + ", receiver=" + receiver);
6500
6501            if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
6502                    != PackageManager.PERMISSION_GRANTED) {
6503                if (receiver != null) {
6504                    // If the caller wants to wait for pending thumbnails,
6505                    // it ain't gonna get them.
6506                    try {
6507                        receiver.finished();
6508                    } catch (RemoteException ex) {
6509                    }
6510                }
6511                String msg = "Permission Denial: getTasks() from pid="
6512                        + Binder.getCallingPid()
6513                        + ", uid=" + Binder.getCallingUid()
6514                        + " requires " + android.Manifest.permission.GET_TASKS;
6515                Log.w(TAG, msg);
6516                throw new SecurityException(msg);
6517            }
6518
6519            int pos = mHistory.size()-1;
6520            HistoryRecord next =
6521                pos >= 0 ? (HistoryRecord)mHistory.get(pos) : null;
6522            HistoryRecord top = null;
6523            CharSequence topDescription = null;
6524            TaskRecord curTask = null;
6525            int numActivities = 0;
6526            int numRunning = 0;
6527            while (pos >= 0 && maxNum > 0) {
6528                final HistoryRecord r = next;
6529                pos--;
6530                next = pos >= 0 ? (HistoryRecord)mHistory.get(pos) : null;
6531
6532                // Initialize state for next task if needed.
6533                if (top == null ||
6534                        (top.state == ActivityState.INITIALIZING
6535                            && top.task == r.task)) {
6536                    top = r;
6537                    topDescription = r.description;
6538                    curTask = r.task;
6539                    numActivities = numRunning = 0;
6540                }
6541
6542                // Add 'r' into the current task.
6543                numActivities++;
6544                if (r.app != null && r.app.thread != null) {
6545                    numRunning++;
6546                }
6547                if (topDescription == null) {
6548                    topDescription = r.description;
6549                }
6550
6551                if (localLOGV) Log.v(
6552                    TAG, r.intent.getComponent().flattenToShortString()
6553                    + ": task=" + r.task);
6554
6555                // If the next one is a different task, generate a new
6556                // TaskInfo entry for what we have.
6557                if (next == null || next.task != curTask) {
6558                    ActivityManager.RunningTaskInfo ci
6559                            = new ActivityManager.RunningTaskInfo();
6560                    ci.id = curTask.taskId;
6561                    ci.baseActivity = r.intent.getComponent();
6562                    ci.topActivity = top.intent.getComponent();
6563                    ci.thumbnail = top.thumbnail;
6564                    ci.description = topDescription;
6565                    ci.numActivities = numActivities;
6566                    ci.numRunning = numRunning;
6567                    //System.out.println(
6568                    //    "#" + maxNum + ": " + " descr=" + ci.description);
6569                    if (ci.thumbnail == null && receiver != null) {
6570                        if (localLOGV) Log.v(
6571                            TAG, "State=" + top.state + "Idle=" + top.idle
6572                            + " app=" + top.app
6573                            + " thr=" + (top.app != null ? top.app.thread : null));
6574                        if (top.state == ActivityState.RESUMED
6575                                || top.state == ActivityState.PAUSING) {
6576                            if (top.idle && top.app != null
6577                                && top.app.thread != null) {
6578                                topRecord = top;
6579                                topThumbnail = top.app.thread;
6580                            } else {
6581                                top.thumbnailNeeded = true;
6582                            }
6583                        }
6584                        if (pending == null) {
6585                            pending = new PendingThumbnailsRecord(receiver);
6586                        }
6587                        pending.pendingRecords.add(top);
6588                    }
6589                    list.add(ci);
6590                    maxNum--;
6591                    top = null;
6592                }
6593            }
6594
6595            if (pending != null) {
6596                mPendingThumbnails.add(pending);
6597            }
6598        }
6599
6600        if (localLOGV) Log.v(TAG, "We have pending thumbnails: " + pending);
6601
6602        if (topThumbnail != null) {
6603            if (localLOGV) Log.v(TAG, "Requesting top thumbnail");
6604            try {
6605                topThumbnail.requestThumbnail(topRecord);
6606            } catch (Exception e) {
6607                Log.w(TAG, "Exception thrown when requesting thumbnail", e);
6608                sendPendingThumbnail(null, topRecord, null, null, true);
6609            }
6610        }
6611
6612        if (pending == null && receiver != null) {
6613            // In this case all thumbnails were available and the client
6614            // is being asked to be told when the remaining ones come in...
6615            // which is unusually, since the top-most currently running
6616            // activity should never have a canned thumbnail!  Oh well.
6617            try {
6618                receiver.finished();
6619            } catch (RemoteException ex) {
6620            }
6621        }
6622
6623        return list;
6624    }
6625
6626    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
6627            int flags) {
6628        synchronized (this) {
6629            enforceCallingPermission(android.Manifest.permission.GET_TASKS,
6630                    "getRecentTasks()");
6631
6632            final int N = mRecentTasks.size();
6633            ArrayList<ActivityManager.RecentTaskInfo> res
6634                    = new ArrayList<ActivityManager.RecentTaskInfo>(
6635                            maxNum < N ? maxNum : N);
6636            for (int i=0; i<N && maxNum > 0; i++) {
6637                TaskRecord tr = mRecentTasks.get(i);
6638                if (((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
6639                        || (tr.intent == null)
6640                        || ((tr.intent.getFlags()
6641                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
6642                    ActivityManager.RecentTaskInfo rti
6643                            = new ActivityManager.RecentTaskInfo();
6644                    rti.id = tr.numActivities > 0 ? tr.taskId : -1;
6645                    rti.baseIntent = new Intent(
6646                            tr.intent != null ? tr.intent : tr.affinityIntent);
6647                    rti.origActivity = tr.origActivity;
6648                    res.add(rti);
6649                    maxNum--;
6650                }
6651            }
6652            return res;
6653        }
6654    }
6655
6656    private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
6657        int j;
6658        TaskRecord startTask = ((HistoryRecord)mHistory.get(startIndex)).task;
6659        TaskRecord jt = startTask;
6660
6661        // First look backwards
6662        for (j=startIndex-1; j>=0; j--) {
6663            HistoryRecord r = (HistoryRecord)mHistory.get(j);
6664            if (r.task != jt) {
6665                jt = r.task;
6666                if (affinity.equals(jt.affinity)) {
6667                    return j;
6668                }
6669            }
6670        }
6671
6672        // Now look forwards
6673        final int N = mHistory.size();
6674        jt = startTask;
6675        for (j=startIndex+1; j<N; j++) {
6676            HistoryRecord r = (HistoryRecord)mHistory.get(j);
6677            if (r.task != jt) {
6678                if (affinity.equals(jt.affinity)) {
6679                    return j;
6680                }
6681                jt = r.task;
6682            }
6683        }
6684
6685        // Might it be at the top?
6686        if (affinity.equals(((HistoryRecord)mHistory.get(N-1)).task.affinity)) {
6687            return N-1;
6688        }
6689
6690        return -1;
6691    }
6692
6693    /**
6694     * Perform a reset of the given task, if needed as part of launching it.
6695     * Returns the new HistoryRecord at the top of the task.
6696     */
6697    private final HistoryRecord resetTaskIfNeededLocked(HistoryRecord taskTop,
6698            HistoryRecord newActivity) {
6699        boolean forceReset = (newActivity.info.flags
6700                &ActivityInfo.FLAG_CLEAR_TASK_ON_LAUNCH) != 0;
6701        if (taskTop.task.getInactiveDuration() > ACTIVITY_INACTIVE_RESET_TIME) {
6702            if ((newActivity.info.flags
6703                    &ActivityInfo.FLAG_ALWAYS_RETAIN_TASK_STATE) == 0) {
6704                forceReset = true;
6705            }
6706        }
6707
6708        final TaskRecord task = taskTop.task;
6709
6710        // We are going to move through the history list so that we can look
6711        // at each activity 'target' with 'below' either the interesting
6712        // activity immediately below it in the stack or null.
6713        HistoryRecord target = null;
6714        int targetI = 0;
6715        int taskTopI = -1;
6716        int replyChainEnd = -1;
6717        int lastReparentPos = -1;
6718        for (int i=mHistory.size()-1; i>=-1; i--) {
6719            HistoryRecord below = i >= 0 ? (HistoryRecord)mHistory.get(i) : null;
6720
6721            if (below != null && below.finishing) {
6722                continue;
6723            }
6724            if (target == null) {
6725                target = below;
6726                targetI = i;
6727                // If we were in the middle of a reply chain before this
6728                // task, it doesn't appear like the root of the chain wants
6729                // anything interesting, so drop it.
6730                replyChainEnd = -1;
6731                continue;
6732            }
6733
6734            final int flags = target.info.flags;
6735
6736            final boolean finishOnTaskLaunch =
6737                (flags&ActivityInfo.FLAG_FINISH_ON_TASK_LAUNCH) != 0;
6738            final boolean allowTaskReparenting =
6739                (flags&ActivityInfo.FLAG_ALLOW_TASK_REPARENTING) != 0;
6740
6741            if (target.task == task) {
6742                // We are inside of the task being reset...  we'll either
6743                // finish this activity, push it out for another task,
6744                // or leave it as-is.  We only do this
6745                // for activities that are not the root of the task (since
6746                // if we finish the root, we may no longer have the task!).
6747                if (taskTopI < 0) {
6748                    taskTopI = targetI;
6749                }
6750                if (below != null && below.task == task) {
6751                    final boolean clearWhenTaskReset =
6752                            (target.intent.getFlags()
6753                                    &Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0;
6754                    if (!finishOnTaskLaunch && !clearWhenTaskReset && target.resultTo != null) {
6755                        // If this activity is sending a reply to a previous
6756                        // activity, we can't do anything with it now until
6757                        // we reach the start of the reply chain.
6758                        // XXX note that we are assuming the result is always
6759                        // to the previous activity, which is almost always
6760                        // the case but we really shouldn't count on.
6761                        if (replyChainEnd < 0) {
6762                            replyChainEnd = targetI;
6763                        }
6764                    } else if (!finishOnTaskLaunch && !clearWhenTaskReset && allowTaskReparenting
6765                            && target.taskAffinity != null
6766                            && !target.taskAffinity.equals(task.affinity)) {
6767                        // If this activity has an affinity for another
6768                        // task, then we need to move it out of here.  We will
6769                        // move it as far out of the way as possible, to the
6770                        // bottom of the activity stack.  This also keeps it
6771                        // correctly ordered with any activities we previously
6772                        // moved.
6773                        HistoryRecord p = (HistoryRecord)mHistory.get(0);
6774                        if (target.taskAffinity != null
6775                                && target.taskAffinity.equals(p.task.affinity)) {
6776                            // If the activity currently at the bottom has the
6777                            // same task affinity as the one we are moving,
6778                            // then merge it into the same task.
6779                            target.task = p.task;
6780                            if (DEBUG_TASKS) Log.v(TAG, "Start pushing activity " + target
6781                                    + " out to bottom task " + p.task);
6782                        } else {
6783                            mCurTask++;
6784                            if (mCurTask <= 0) {
6785                                mCurTask = 1;
6786                            }
6787                            target.task = new TaskRecord(mCurTask, target.info, null,
6788                                    (target.info.flags&ActivityInfo.FLAG_CLEAR_TASK_ON_LAUNCH) != 0);
6789                            target.task.affinityIntent = target.intent;
6790                            if (DEBUG_TASKS) Log.v(TAG, "Start pushing activity " + target
6791                                    + " out to new task " + target.task);
6792                        }
6793                        mWindowManager.setAppGroupId(target, task.taskId);
6794                        if (replyChainEnd < 0) {
6795                            replyChainEnd = targetI;
6796                        }
6797                        int dstPos = 0;
6798                        for (int srcPos=targetI; srcPos<=replyChainEnd; srcPos++) {
6799                            p = (HistoryRecord)mHistory.get(srcPos);
6800                            if (p.finishing) {
6801                                continue;
6802                            }
6803                            if (DEBUG_TASKS) Log.v(TAG, "Pushing next activity " + p
6804                                    + " out to target's task " + target.task);
6805                            task.numActivities--;
6806                            p.task = target.task;
6807                            target.task.numActivities++;
6808                            mHistory.remove(srcPos);
6809                            mHistory.add(dstPos, p);
6810                            mWindowManager.moveAppToken(dstPos, p);
6811                            mWindowManager.setAppGroupId(p, p.task.taskId);
6812                            dstPos++;
6813                            if (VALIDATE_TOKENS) {
6814                                mWindowManager.validateAppTokens(mHistory);
6815                            }
6816                            i++;
6817                        }
6818                        if (taskTop == p) {
6819                            taskTop = below;
6820                        }
6821                        if (taskTopI == replyChainEnd) {
6822                            taskTopI = -1;
6823                        }
6824                        replyChainEnd = -1;
6825                        addRecentTask(target.task);
6826                    } else if (forceReset || finishOnTaskLaunch
6827                            || clearWhenTaskReset) {
6828                        // If the activity should just be removed -- either
6829                        // because it asks for it, or the task should be
6830                        // cleared -- then finish it and anything that is
6831                        // part of its reply chain.
6832                        if (clearWhenTaskReset) {
6833                            // In this case, we want to finish this activity
6834                            // and everything above it, so be sneaky and pretend
6835                            // like these are all in the reply chain.
6836                            replyChainEnd = targetI+1;
6837                            while (replyChainEnd < mHistory.size() &&
6838                                    ((HistoryRecord)mHistory.get(
6839                                                replyChainEnd)).task == task) {
6840                                replyChainEnd++;
6841                            }
6842                            replyChainEnd--;
6843                        } else if (replyChainEnd < 0) {
6844                            replyChainEnd = targetI;
6845                        }
6846                        HistoryRecord p = null;
6847                        for (int srcPos=targetI; srcPos<=replyChainEnd; srcPos++) {
6848                            p = (HistoryRecord)mHistory.get(srcPos);
6849                            if (p.finishing) {
6850                                continue;
6851                            }
6852                            if (finishActivityLocked(p, srcPos,
6853                                    Activity.RESULT_CANCELED, null, "reset")) {
6854                                replyChainEnd--;
6855                                srcPos--;
6856                            }
6857                        }
6858                        if (taskTop == p) {
6859                            taskTop = below;
6860                        }
6861                        if (taskTopI == replyChainEnd) {
6862                            taskTopI = -1;
6863                        }
6864                        replyChainEnd = -1;
6865                    } else {
6866                        // If we were in the middle of a chain, well the
6867                        // activity that started it all doesn't want anything
6868                        // special, so leave it all as-is.
6869                        replyChainEnd = -1;
6870                    }
6871                } else {
6872                    // Reached the bottom of the task -- any reply chain
6873                    // should be left as-is.
6874                    replyChainEnd = -1;
6875                }
6876
6877            } else if (target.resultTo != null) {
6878                // If this activity is sending a reply to a previous
6879                // activity, we can't do anything with it now until
6880                // we reach the start of the reply chain.
6881                // XXX note that we are assuming the result is always
6882                // to the previous activity, which is almost always
6883                // the case but we really shouldn't count on.
6884                if (replyChainEnd < 0) {
6885                    replyChainEnd = targetI;
6886                }
6887
6888            } else if (taskTopI >= 0 && allowTaskReparenting
6889                    && task.affinity != null
6890                    && task.affinity.equals(target.taskAffinity)) {
6891                // We are inside of another task...  if this activity has
6892                // an affinity for our task, then either remove it if we are
6893                // clearing or move it over to our task.  Note that
6894                // we currently punt on the case where we are resetting a
6895                // task that is not at the top but who has activities above
6896                // with an affinity to it...  this is really not a normal
6897                // case, and we will need to later pull that task to the front
6898                // and usually at that point we will do the reset and pick
6899                // up those remaining activities.  (This only happens if
6900                // someone starts an activity in a new task from an activity
6901                // in a task that is not currently on top.)
6902                if (forceReset || finishOnTaskLaunch) {
6903                    if (replyChainEnd < 0) {
6904                        replyChainEnd = targetI;
6905                    }
6906                    HistoryRecord p = null;
6907                    for (int srcPos=targetI; srcPos<=replyChainEnd; srcPos++) {
6908                        p = (HistoryRecord)mHistory.get(srcPos);
6909                        if (p.finishing) {
6910                            continue;
6911                        }
6912                        if (finishActivityLocked(p, srcPos,
6913                                Activity.RESULT_CANCELED, null, "reset")) {
6914                            taskTopI--;
6915                            lastReparentPos--;
6916                            replyChainEnd--;
6917                            srcPos--;
6918                        }
6919                    }
6920                    replyChainEnd = -1;
6921                } else {
6922                    if (replyChainEnd < 0) {
6923                        replyChainEnd = targetI;
6924                    }
6925                    for (int srcPos=replyChainEnd; srcPos>=targetI; srcPos--) {
6926                        HistoryRecord p = (HistoryRecord)mHistory.get(srcPos);
6927                        if (p.finishing) {
6928                            continue;
6929                        }
6930                        if (lastReparentPos < 0) {
6931                            lastReparentPos = taskTopI;
6932                            taskTop = p;
6933                        } else {
6934                            lastReparentPos--;
6935                        }
6936                        mHistory.remove(srcPos);
6937                        p.task.numActivities--;
6938                        p.task = task;
6939                        mHistory.add(lastReparentPos, p);
6940                        if (DEBUG_TASKS) Log.v(TAG, "Pulling activity " + p
6941                                + " in to resetting task " + task);
6942                        task.numActivities++;
6943                        mWindowManager.moveAppToken(lastReparentPos, p);
6944                        mWindowManager.setAppGroupId(p, p.task.taskId);
6945                        if (VALIDATE_TOKENS) {
6946                            mWindowManager.validateAppTokens(mHistory);
6947                        }
6948                    }
6949                    replyChainEnd = -1;
6950
6951                    // Now we've moved it in to place...  but what if this is
6952                    // a singleTop activity and we have put it on top of another
6953                    // instance of the same activity?  Then we drop the instance
6954                    // below so it remains singleTop.
6955                    if (target.info.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP) {
6956                        for (int j=lastReparentPos-1; j>=0; j--) {
6957                            HistoryRecord p = (HistoryRecord)mHistory.get(j);
6958                            if (p.finishing) {
6959                                continue;
6960                            }
6961                            if (p.intent.getComponent().equals(target.intent.getComponent())) {
6962                                if (finishActivityLocked(p, j,
6963                                        Activity.RESULT_CANCELED, null, "replace")) {
6964                                    taskTopI--;
6965                                    lastReparentPos--;
6966                                }
6967                            }
6968                        }
6969                    }
6970                }
6971            }
6972
6973            target = below;
6974            targetI = i;
6975        }
6976
6977        return taskTop;
6978    }
6979
6980    /**
6981     * TODO: Add mController hook
6982     */
6983    public void moveTaskToFront(int task) {
6984        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
6985                "moveTaskToFront()");
6986
6987        synchronized(this) {
6988            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
6989                    Binder.getCallingUid(), "Task to front")) {
6990                return;
6991            }
6992            final long origId = Binder.clearCallingIdentity();
6993            try {
6994                int N = mRecentTasks.size();
6995                for (int i=0; i<N; i++) {
6996                    TaskRecord tr = mRecentTasks.get(i);
6997                    if (tr.taskId == task) {
6998                        moveTaskToFrontLocked(tr, null);
6999                        return;
7000                    }
7001                }
7002                for (int i=mHistory.size()-1; i>=0; i--) {
7003                    HistoryRecord hr = (HistoryRecord)mHistory.get(i);
7004                    if (hr.task.taskId == task) {
7005                        moveTaskToFrontLocked(hr.task, null);
7006                        return;
7007                    }
7008                }
7009            } finally {
7010                Binder.restoreCallingIdentity(origId);
7011            }
7012        }
7013    }
7014
7015    private final void moveTaskToFrontLocked(TaskRecord tr, HistoryRecord reason) {
7016        if (DEBUG_SWITCH) Log.v(TAG, "moveTaskToFront: " + tr);
7017
7018        final int task = tr.taskId;
7019        int top = mHistory.size()-1;
7020
7021        if (top < 0 || ((HistoryRecord)mHistory.get(top)).task.taskId == task) {
7022            // nothing to do!
7023            return;
7024        }
7025
7026        ArrayList moved = new ArrayList();
7027
7028        // Applying the affinities may have removed entries from the history,
7029        // so get the size again.
7030        top = mHistory.size()-1;
7031        int pos = top;
7032
7033        // Shift all activities with this task up to the top
7034        // of the stack, keeping them in the same internal order.
7035        while (pos >= 0) {
7036            HistoryRecord r = (HistoryRecord)mHistory.get(pos);
7037            if (localLOGV) Log.v(
7038                TAG, "At " + pos + " ckp " + r.task + ": " + r);
7039            boolean first = true;
7040            if (r.task.taskId == task) {
7041                if (localLOGV) Log.v(TAG, "Removing and adding at " + top);
7042                mHistory.remove(pos);
7043                mHistory.add(top, r);
7044                moved.add(0, r);
7045                top--;
7046                if (first) {
7047                    addRecentTask(r.task);
7048                    first = false;
7049                }
7050            }
7051            pos--;
7052        }
7053
7054        if (DEBUG_TRANSITION) Log.v(TAG,
7055                "Prepare to front transition: task=" + tr);
7056        if (reason != null &&
7057                (reason.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) {
7058            mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_NONE);
7059            HistoryRecord r = topRunningActivityLocked(null);
7060            if (r != null) {
7061                mNoAnimActivities.add(r);
7062            }
7063        } else {
7064            mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_TASK_TO_FRONT);
7065        }
7066
7067        mWindowManager.moveAppTokensToTop(moved);
7068        if (VALIDATE_TOKENS) {
7069            mWindowManager.validateAppTokens(mHistory);
7070        }
7071
7072        finishTaskMove(task);
7073        EventLog.writeEvent(EventLogTags.AM_TASK_TO_FRONT, task);
7074    }
7075
7076    private final void finishTaskMove(int task) {
7077        resumeTopActivityLocked(null);
7078    }
7079
7080    public void moveTaskToBack(int task) {
7081        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7082                "moveTaskToBack()");
7083
7084        synchronized(this) {
7085            if (mResumedActivity != null && mResumedActivity.task.taskId == task) {
7086                if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7087                        Binder.getCallingUid(), "Task to back")) {
7088                    return;
7089                }
7090            }
7091            final long origId = Binder.clearCallingIdentity();
7092            moveTaskToBackLocked(task, null);
7093            Binder.restoreCallingIdentity(origId);
7094        }
7095    }
7096
7097    /**
7098     * Moves an activity, and all of the other activities within the same task, to the bottom
7099     * of the history stack.  The activity's order within the task is unchanged.
7100     *
7101     * @param token A reference to the activity we wish to move
7102     * @param nonRoot If false then this only works if the activity is the root
7103     *                of a task; if true it will work for any activity in a task.
7104     * @return Returns true if the move completed, false if not.
7105     */
7106    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7107        synchronized(this) {
7108            final long origId = Binder.clearCallingIdentity();
7109            int taskId = getTaskForActivityLocked(token, !nonRoot);
7110            if (taskId >= 0) {
7111                return moveTaskToBackLocked(taskId, null);
7112            }
7113            Binder.restoreCallingIdentity(origId);
7114        }
7115        return false;
7116    }
7117
7118    /**
7119     * Worker method for rearranging history stack.  Implements the function of moving all
7120     * activities for a specific task (gathering them if disjoint) into a single group at the
7121     * bottom of the stack.
7122     *
7123     * If a watcher is installed, the action is preflighted and the watcher has an opportunity
7124     * to premeptively cancel the move.
7125     *
7126     * @param task The taskId to collect and move to the bottom.
7127     * @return Returns true if the move completed, false if not.
7128     */
7129    private final boolean moveTaskToBackLocked(int task, HistoryRecord reason) {
7130        Log.i(TAG, "moveTaskToBack: " + task);
7131
7132        // If we have a watcher, preflight the move before committing to it.  First check
7133        // for *other* available tasks, but if none are available, then try again allowing the
7134        // current task to be selected.
7135        if (mController != null) {
7136            HistoryRecord next = topRunningActivityLocked(null, task);
7137            if (next == null) {
7138                next = topRunningActivityLocked(null, 0);
7139            }
7140            if (next != null) {
7141                // ask watcher if this is allowed
7142                boolean moveOK = true;
7143                try {
7144                    moveOK = mController.activityResuming(next.packageName);
7145                } catch (RemoteException e) {
7146                    mController = null;
7147                }
7148                if (!moveOK) {
7149                    return false;
7150                }
7151            }
7152        }
7153
7154        ArrayList moved = new ArrayList();
7155
7156        if (DEBUG_TRANSITION) Log.v(TAG,
7157                "Prepare to back transition: task=" + task);
7158
7159        final int N = mHistory.size();
7160        int bottom = 0;
7161        int pos = 0;
7162
7163        // Shift all activities with this task down to the bottom
7164        // of the stack, keeping them in the same internal order.
7165        while (pos < N) {
7166            HistoryRecord r = (HistoryRecord)mHistory.get(pos);
7167            if (localLOGV) Log.v(
7168                TAG, "At " + pos + " ckp " + r.task + ": " + r);
7169            if (r.task.taskId == task) {
7170                if (localLOGV) Log.v(TAG, "Removing and adding at " + (N-1));
7171                mHistory.remove(pos);
7172                mHistory.add(bottom, r);
7173                moved.add(r);
7174                bottom++;
7175            }
7176            pos++;
7177        }
7178
7179        if (reason != null &&
7180                (reason.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) {
7181            mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_NONE);
7182            HistoryRecord r = topRunningActivityLocked(null);
7183            if (r != null) {
7184                mNoAnimActivities.add(r);
7185            }
7186        } else {
7187            mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_TASK_TO_BACK);
7188        }
7189        mWindowManager.moveAppTokensToBottom(moved);
7190        if (VALIDATE_TOKENS) {
7191            mWindowManager.validateAppTokens(mHistory);
7192        }
7193
7194        finishTaskMove(task);
7195        return true;
7196    }
7197
7198    public void moveTaskBackwards(int task) {
7199        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7200                "moveTaskBackwards()");
7201
7202        synchronized(this) {
7203            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7204                    Binder.getCallingUid(), "Task backwards")) {
7205                return;
7206            }
7207            final long origId = Binder.clearCallingIdentity();
7208            moveTaskBackwardsLocked(task);
7209            Binder.restoreCallingIdentity(origId);
7210        }
7211    }
7212
7213    private final void moveTaskBackwardsLocked(int task) {
7214        Log.e(TAG, "moveTaskBackwards not yet implemented!");
7215    }
7216
7217    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7218        synchronized(this) {
7219            return getTaskForActivityLocked(token, onlyRoot);
7220        }
7221    }
7222
7223    int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
7224        final int N = mHistory.size();
7225        TaskRecord lastTask = null;
7226        for (int i=0; i<N; i++) {
7227            HistoryRecord r = (HistoryRecord)mHistory.get(i);
7228            if (r == token) {
7229                if (!onlyRoot || lastTask != r.task) {
7230                    return r.task.taskId;
7231                }
7232                return -1;
7233            }
7234            lastTask = r.task;
7235        }
7236
7237        return -1;
7238    }
7239
7240    /**
7241     * Returns the top activity in any existing task matching the given
7242     * Intent.  Returns null if no such task is found.
7243     */
7244    private HistoryRecord findTaskLocked(Intent intent, ActivityInfo info) {
7245        ComponentName cls = intent.getComponent();
7246        if (info.targetActivity != null) {
7247            cls = new ComponentName(info.packageName, info.targetActivity);
7248        }
7249
7250        TaskRecord cp = null;
7251
7252        final int N = mHistory.size();
7253        for (int i=(N-1); i>=0; i--) {
7254            HistoryRecord r = (HistoryRecord)mHistory.get(i);
7255            if (!r.finishing && r.task != cp
7256                    && r.launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
7257                cp = r.task;
7258                //Log.i(TAG, "Comparing existing cls=" + r.task.intent.getComponent().flattenToShortString()
7259                //        + "/aff=" + r.task.affinity + " to new cls="
7260                //        + intent.getComponent().flattenToShortString() + "/aff=" + taskAffinity);
7261                if (r.task.affinity != null) {
7262                    if (r.task.affinity.equals(info.taskAffinity)) {
7263                        //Log.i(TAG, "Found matching affinity!");
7264                        return r;
7265                    }
7266                } else if (r.task.intent != null
7267                        && r.task.intent.getComponent().equals(cls)) {
7268                    //Log.i(TAG, "Found matching class!");
7269                    //dump();
7270                    //Log.i(TAG, "For Intent " + intent + " bringing to top: " + r.intent);
7271                    return r;
7272                } else if (r.task.affinityIntent != null
7273                        && r.task.affinityIntent.getComponent().equals(cls)) {
7274                    //Log.i(TAG, "Found matching class!");
7275                    //dump();
7276                    //Log.i(TAG, "For Intent " + intent + " bringing to top: " + r.intent);
7277                    return r;
7278                }
7279            }
7280        }
7281
7282        return null;
7283    }
7284
7285    /**
7286     * Returns the first activity (starting from the top of the stack) that
7287     * is the same as the given activity.  Returns null if no such activity
7288     * is found.
7289     */
7290    private HistoryRecord findActivityLocked(Intent intent, ActivityInfo info) {
7291        ComponentName cls = intent.getComponent();
7292        if (info.targetActivity != null) {
7293            cls = new ComponentName(info.packageName, info.targetActivity);
7294        }
7295
7296        final int N = mHistory.size();
7297        for (int i=(N-1); i>=0; i--) {
7298            HistoryRecord r = (HistoryRecord)mHistory.get(i);
7299            if (!r.finishing) {
7300                if (r.intent.getComponent().equals(cls)) {
7301                    //Log.i(TAG, "Found matching class!");
7302                    //dump();
7303                    //Log.i(TAG, "For Intent " + intent + " bringing to top: " + r.intent);
7304                    return r;
7305                }
7306            }
7307        }
7308
7309        return null;
7310    }
7311
7312    public void finishOtherInstances(IBinder token, ComponentName className) {
7313        synchronized(this) {
7314            final long origId = Binder.clearCallingIdentity();
7315
7316            int N = mHistory.size();
7317            TaskRecord lastTask = null;
7318            for (int i=0; i<N; i++) {
7319                HistoryRecord r = (HistoryRecord)mHistory.get(i);
7320                if (r.realActivity.equals(className)
7321                        && r != token && lastTask != r.task) {
7322                    if (finishActivityLocked(r, i, Activity.RESULT_CANCELED,
7323                            null, "others")) {
7324                        i--;
7325                        N--;
7326                    }
7327                }
7328                lastTask = r.task;
7329            }
7330
7331            Binder.restoreCallingIdentity(origId);
7332        }
7333    }
7334
7335    // =========================================================
7336    // THUMBNAILS
7337    // =========================================================
7338
7339    public void reportThumbnail(IBinder token,
7340            Bitmap thumbnail, CharSequence description) {
7341        //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
7342        final long origId = Binder.clearCallingIdentity();
7343        sendPendingThumbnail(null, token, thumbnail, description, true);
7344        Binder.restoreCallingIdentity(origId);
7345    }
7346
7347    final void sendPendingThumbnail(HistoryRecord r, IBinder token,
7348            Bitmap thumbnail, CharSequence description, boolean always) {
7349        TaskRecord task = null;
7350        ArrayList receivers = null;
7351
7352        //System.out.println("Send pending thumbnail: " + r);
7353
7354        synchronized(this) {
7355            if (r == null) {
7356                int index = indexOfTokenLocked(token);
7357                if (index < 0) {
7358                    return;
7359                }
7360                r = (HistoryRecord)mHistory.get(index);
7361            }
7362            if (thumbnail == null) {
7363                thumbnail = r.thumbnail;
7364                description = r.description;
7365            }
7366            if (thumbnail == null && !always) {
7367                // If there is no thumbnail, and this entry is not actually
7368                // going away, then abort for now and pick up the next
7369                // thumbnail we get.
7370                return;
7371            }
7372            task = r.task;
7373
7374            int N = mPendingThumbnails.size();
7375            int i=0;
7376            while (i<N) {
7377                PendingThumbnailsRecord pr =
7378                    (PendingThumbnailsRecord)mPendingThumbnails.get(i);
7379                //System.out.println("Looking in " + pr.pendingRecords);
7380                if (pr.pendingRecords.remove(r)) {
7381                    if (receivers == null) {
7382                        receivers = new ArrayList();
7383                    }
7384                    receivers.add(pr);
7385                    if (pr.pendingRecords.size() == 0) {
7386                        pr.finished = true;
7387                        mPendingThumbnails.remove(i);
7388                        N--;
7389                        continue;
7390                    }
7391                }
7392                i++;
7393            }
7394        }
7395
7396        if (receivers != null) {
7397            final int N = receivers.size();
7398            for (int i=0; i<N; i++) {
7399                try {
7400                    PendingThumbnailsRecord pr =
7401                        (PendingThumbnailsRecord)receivers.get(i);
7402                    pr.receiver.newThumbnail(
7403                        task != null ? task.taskId : -1, thumbnail, description);
7404                    if (pr.finished) {
7405                        pr.receiver.finished();
7406                    }
7407                } catch (Exception e) {
7408                    Log.w(TAG, "Exception thrown when sending thumbnail", e);
7409                }
7410            }
7411        }
7412    }
7413
7414    // =========================================================
7415    // CONTENT PROVIDERS
7416    // =========================================================
7417
7418    private final List generateApplicationProvidersLocked(ProcessRecord app) {
7419        List providers = null;
7420        try {
7421            providers = ActivityThread.getPackageManager().
7422                queryContentProviders(app.processName, app.info.uid,
7423                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
7424        } catch (RemoteException ex) {
7425        }
7426        if (providers != null) {
7427            final int N = providers.size();
7428            for (int i=0; i<N; i++) {
7429                ProviderInfo cpi =
7430                    (ProviderInfo)providers.get(i);
7431                ContentProviderRecord cpr =
7432                    (ContentProviderRecord)mProvidersByClass.get(cpi.name);
7433                if (cpr == null) {
7434                    cpr = new ContentProviderRecord(cpi, app.info);
7435                    mProvidersByClass.put(cpi.name, cpr);
7436                }
7437                app.pubProviders.put(cpi.name, cpr);
7438                app.addPackage(cpi.applicationInfo.packageName);
7439                ensurePackageDexOpt(cpi.applicationInfo.packageName);
7440            }
7441        }
7442        return providers;
7443    }
7444
7445    private final String checkContentProviderPermissionLocked(
7446            ProviderInfo cpi, ProcessRecord r, int mode) {
7447        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
7448        final int callingUid = (r != null) ? r.info.uid : Binder.getCallingUid();
7449        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
7450                cpi.exported ? -1 : cpi.applicationInfo.uid)
7451                == PackageManager.PERMISSION_GRANTED
7452                && mode == ParcelFileDescriptor.MODE_READ_ONLY || mode == -1) {
7453            return null;
7454        }
7455        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
7456                cpi.exported ? -1 : cpi.applicationInfo.uid)
7457                == PackageManager.PERMISSION_GRANTED) {
7458            return null;
7459        }
7460
7461        PathPermission[] pps = cpi.pathPermissions;
7462        if (pps != null) {
7463            int i = pps.length;
7464            while (i > 0) {
7465                i--;
7466                PathPermission pp = pps[i];
7467                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
7468                        cpi.exported ? -1 : cpi.applicationInfo.uid)
7469                        == PackageManager.PERMISSION_GRANTED
7470                        && mode == ParcelFileDescriptor.MODE_READ_ONLY || mode == -1) {
7471                    return null;
7472                }
7473                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
7474                        cpi.exported ? -1 : cpi.applicationInfo.uid)
7475                        == PackageManager.PERMISSION_GRANTED) {
7476                    return null;
7477                }
7478            }
7479        }
7480
7481        String msg = "Permission Denial: opening provider " + cpi.name
7482                + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7483                + ", uid=" + callingUid + ") requires "
7484                + cpi.readPermission + " or " + cpi.writePermission;
7485        Log.w(TAG, msg);
7486        return msg;
7487    }
7488
7489    private final ContentProviderHolder getContentProviderImpl(
7490        IApplicationThread caller, String name) {
7491        ContentProviderRecord cpr;
7492        ProviderInfo cpi = null;
7493
7494        synchronized(this) {
7495            ProcessRecord r = null;
7496            if (caller != null) {
7497                r = getRecordForAppLocked(caller);
7498                if (r == null) {
7499                    throw new SecurityException(
7500                            "Unable to find app for caller " + caller
7501                          + " (pid=" + Binder.getCallingPid()
7502                          + ") when getting content provider " + name);
7503                }
7504            }
7505
7506            // First check if this content provider has been published...
7507            cpr = (ContentProviderRecord)mProvidersByName.get(name);
7508            if (cpr != null) {
7509                cpi = cpr.info;
7510                if (checkContentProviderPermissionLocked(cpi, r, -1) != null) {
7511                    return new ContentProviderHolder(cpi,
7512                            cpi.readPermission != null
7513                                    ? cpi.readPermission : cpi.writePermission);
7514                }
7515
7516                if (r != null && cpr.canRunHere(r)) {
7517                    // This provider has been published or is in the process
7518                    // of being published...  but it is also allowed to run
7519                    // in the caller's process, so don't make a connection
7520                    // and just let the caller instantiate its own instance.
7521                    if (cpr.provider != null) {
7522                        // don't give caller the provider object, it needs
7523                        // to make its own.
7524                        cpr = new ContentProviderRecord(cpr);
7525                    }
7526                    return cpr;
7527                }
7528
7529                final long origId = Binder.clearCallingIdentity();
7530
7531                // In this case the provider instance already exists, so we can
7532                // return it right away.
7533                if (r != null) {
7534                    if (DEBUG_PROVIDER) Log.v(TAG,
7535                            "Adding provider requested by "
7536                            + r.processName + " from process "
7537                            + cpr.info.processName);
7538                    Integer cnt = r.conProviders.get(cpr);
7539                    if (cnt == null) {
7540                        r.conProviders.put(cpr, new Integer(1));
7541                    } else {
7542                        r.conProviders.put(cpr, new Integer(cnt.intValue()+1));
7543                    }
7544                    cpr.clients.add(r);
7545                } else {
7546                    cpr.externals++;
7547                }
7548
7549                if (cpr.app != null) {
7550                    updateOomAdjLocked(cpr.app);
7551                }
7552
7553                Binder.restoreCallingIdentity(origId);
7554
7555            } else {
7556                try {
7557                    cpi = ActivityThread.getPackageManager().
7558                        resolveContentProvider(name,
7559                                STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
7560                } catch (RemoteException ex) {
7561                }
7562                if (cpi == null) {
7563                    return null;
7564                }
7565
7566                if (checkContentProviderPermissionLocked(cpi, r, -1) != null) {
7567                    return new ContentProviderHolder(cpi,
7568                            cpi.readPermission != null
7569                                    ? cpi.readPermission : cpi.writePermission);
7570                }
7571
7572                cpr = (ContentProviderRecord)mProvidersByClass.get(cpi.name);
7573                final boolean firstClass = cpr == null;
7574                if (firstClass) {
7575                    try {
7576                        ApplicationInfo ai =
7577                            ActivityThread.getPackageManager().
7578                                getApplicationInfo(
7579                                        cpi.applicationInfo.packageName,
7580                                        STOCK_PM_FLAGS);
7581                        if (ai == null) {
7582                            Log.w(TAG, "No package info for content provider "
7583                                    + cpi.name);
7584                            return null;
7585                        }
7586                        cpr = new ContentProviderRecord(cpi, ai);
7587                    } catch (RemoteException ex) {
7588                        // pm is in same process, this will never happen.
7589                    }
7590                }
7591
7592                if (r != null && cpr.canRunHere(r)) {
7593                    // If this is a multiprocess provider, then just return its
7594                    // info and allow the caller to instantiate it.  Only do
7595                    // this if the provider is the same user as the caller's
7596                    // process, or can run as root (so can be in any process).
7597                    return cpr;
7598                }
7599
7600                if (DEBUG_PROVIDER) {
7601                    RuntimeException e = new RuntimeException("here");
7602                    Log.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.info.uid
7603                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
7604                }
7605
7606                // This is single process, and our app is now connecting to it.
7607                // See if we are already in the process of launching this
7608                // provider.
7609                final int N = mLaunchingProviders.size();
7610                int i;
7611                for (i=0; i<N; i++) {
7612                    if (mLaunchingProviders.get(i) == cpr) {
7613                        break;
7614                    }
7615                }
7616
7617                // If the provider is not already being launched, then get it
7618                // started.
7619                if (i >= N) {
7620                    final long origId = Binder.clearCallingIdentity();
7621                    ProcessRecord proc = startProcessLocked(cpi.processName,
7622                            cpr.appInfo, false, 0, "content provider",
7623                            new ComponentName(cpi.applicationInfo.packageName,
7624                                    cpi.name), false);
7625                    if (proc == null) {
7626                        Log.w(TAG, "Unable to launch app "
7627                                + cpi.applicationInfo.packageName + "/"
7628                                + cpi.applicationInfo.uid + " for provider "
7629                                + name + ": process is bad");
7630                        return null;
7631                    }
7632                    cpr.launchingApp = proc;
7633                    mLaunchingProviders.add(cpr);
7634                    Binder.restoreCallingIdentity(origId);
7635                }
7636
7637                // Make sure the provider is published (the same provider class
7638                // may be published under multiple names).
7639                if (firstClass) {
7640                    mProvidersByClass.put(cpi.name, cpr);
7641                }
7642                mProvidersByName.put(name, cpr);
7643
7644                if (r != null) {
7645                    if (DEBUG_PROVIDER) Log.v(TAG,
7646                            "Adding provider requested by "
7647                            + r.processName + " from process "
7648                            + cpr.info.processName);
7649                    Integer cnt = r.conProviders.get(cpr);
7650                    if (cnt == null) {
7651                        r.conProviders.put(cpr, new Integer(1));
7652                    } else {
7653                        r.conProviders.put(cpr, new Integer(cnt.intValue()+1));
7654                    }
7655                    cpr.clients.add(r);
7656                } else {
7657                    cpr.externals++;
7658                }
7659            }
7660        }
7661
7662        // Wait for the provider to be published...
7663        synchronized (cpr) {
7664            while (cpr.provider == null) {
7665                if (cpr.launchingApp == null) {
7666                    Log.w(TAG, "Unable to launch app "
7667                            + cpi.applicationInfo.packageName + "/"
7668                            + cpi.applicationInfo.uid + " for provider "
7669                            + name + ": launching app became null");
7670                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
7671                            cpi.applicationInfo.packageName,
7672                            cpi.applicationInfo.uid, name);
7673                    return null;
7674                }
7675                try {
7676                    cpr.wait();
7677                } catch (InterruptedException ex) {
7678                }
7679            }
7680        }
7681        return cpr;
7682    }
7683
7684    public final ContentProviderHolder getContentProvider(
7685            IApplicationThread caller, String name) {
7686        if (caller == null) {
7687            String msg = "null IApplicationThread when getting content provider "
7688                    + name;
7689            Log.w(TAG, msg);
7690            throw new SecurityException(msg);
7691        }
7692
7693        return getContentProviderImpl(caller, name);
7694    }
7695
7696    private ContentProviderHolder getContentProviderExternal(String name) {
7697        return getContentProviderImpl(null, name);
7698    }
7699
7700    /**
7701     * Drop a content provider from a ProcessRecord's bookkeeping
7702     * @param cpr
7703     */
7704    public void removeContentProvider(IApplicationThread caller, String name) {
7705        synchronized (this) {
7706            ContentProviderRecord cpr = (ContentProviderRecord)mProvidersByName.get(name);
7707            if(cpr == null) {
7708                // remove from mProvidersByClass
7709                if (DEBUG_PROVIDER) Log.v(TAG, name +
7710                        " provider not found in providers list");
7711                return;
7712            }
7713            final ProcessRecord r = getRecordForAppLocked(caller);
7714            if (r == null) {
7715                throw new SecurityException(
7716                        "Unable to find app for caller " + caller +
7717                        " when removing content provider " + name);
7718            }
7719            //update content provider record entry info
7720            ContentProviderRecord localCpr = (ContentProviderRecord)
7721                    mProvidersByClass.get(cpr.info.name);
7722            if (DEBUG_PROVIDER) Log.v(TAG, "Removing provider requested by "
7723                    + r.info.processName + " from process "
7724                    + localCpr.appInfo.processName);
7725            if (localCpr.app == r) {
7726                //should not happen. taken care of as a local provider
7727                Log.w(TAG, "removeContentProvider called on local provider: "
7728                        + cpr.info.name + " in process " + r.processName);
7729                return;
7730            } else {
7731                Integer cnt = r.conProviders.get(localCpr);
7732                if (cnt == null || cnt.intValue() <= 1) {
7733                    localCpr.clients.remove(r);
7734                    r.conProviders.remove(localCpr);
7735                } else {
7736                    r.conProviders.put(localCpr, new Integer(cnt.intValue()-1));
7737                }
7738            }
7739            updateOomAdjLocked();
7740        }
7741    }
7742
7743    private void removeContentProviderExternal(String name) {
7744        synchronized (this) {
7745            ContentProviderRecord cpr = (ContentProviderRecord)mProvidersByName.get(name);
7746            if(cpr == null) {
7747                //remove from mProvidersByClass
7748                if(localLOGV) Log.v(TAG, name+" content provider not found in providers list");
7749                return;
7750            }
7751
7752            //update content provider record entry info
7753            ContentProviderRecord localCpr = (ContentProviderRecord) mProvidersByClass.get(cpr.info.name);
7754            localCpr.externals--;
7755            if (localCpr.externals < 0) {
7756                Log.e(TAG, "Externals < 0 for content provider " + localCpr);
7757            }
7758            updateOomAdjLocked();
7759        }
7760    }
7761
7762    public final void publishContentProviders(IApplicationThread caller,
7763            List<ContentProviderHolder> providers) {
7764        if (providers == null) {
7765            return;
7766        }
7767
7768        synchronized(this) {
7769            final ProcessRecord r = getRecordForAppLocked(caller);
7770            if (r == null) {
7771                throw new SecurityException(
7772                        "Unable to find app for caller " + caller
7773                      + " (pid=" + Binder.getCallingPid()
7774                      + ") when publishing content providers");
7775            }
7776
7777            final long origId = Binder.clearCallingIdentity();
7778
7779            final int N = providers.size();
7780            for (int i=0; i<N; i++) {
7781                ContentProviderHolder src = providers.get(i);
7782                if (src == null || src.info == null || src.provider == null) {
7783                    continue;
7784                }
7785                ContentProviderRecord dst =
7786                    (ContentProviderRecord)r.pubProviders.get(src.info.name);
7787                if (dst != null) {
7788                    mProvidersByClass.put(dst.info.name, dst);
7789                    String names[] = dst.info.authority.split(";");
7790                    for (int j = 0; j < names.length; j++) {
7791                        mProvidersByName.put(names[j], dst);
7792                    }
7793
7794                    int NL = mLaunchingProviders.size();
7795                    int j;
7796                    for (j=0; j<NL; j++) {
7797                        if (mLaunchingProviders.get(j) == dst) {
7798                            mLaunchingProviders.remove(j);
7799                            j--;
7800                            NL--;
7801                        }
7802                    }
7803                    synchronized (dst) {
7804                        dst.provider = src.provider;
7805                        dst.app = r;
7806                        dst.notifyAll();
7807                    }
7808                    updateOomAdjLocked(r);
7809                }
7810            }
7811
7812            Binder.restoreCallingIdentity(origId);
7813        }
7814    }
7815
7816    public static final void installSystemProviders() {
7817        ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
7818        List providers = mSelf.generateApplicationProvidersLocked(app);
7819        mSystemThread.installSystemProviders(providers);
7820    }
7821
7822    // =========================================================
7823    // GLOBAL MANAGEMENT
7824    // =========================================================
7825
7826    final ProcessRecord newProcessRecordLocked(IApplicationThread thread,
7827            ApplicationInfo info, String customProcess) {
7828        String proc = customProcess != null ? customProcess : info.processName;
7829        BatteryStatsImpl.Uid.Proc ps = null;
7830        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
7831        synchronized (stats) {
7832            ps = stats.getProcessStatsLocked(info.uid, proc);
7833        }
7834        return new ProcessRecord(ps, thread, info, proc);
7835    }
7836
7837    final ProcessRecord addAppLocked(ApplicationInfo info) {
7838        ProcessRecord app = getProcessRecordLocked(info.processName, info.uid);
7839
7840        if (app == null) {
7841            app = newProcessRecordLocked(null, info, null);
7842            mProcessNames.put(info.processName, info.uid, app);
7843            updateLruProcessLocked(app, true, true);
7844        }
7845
7846        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
7847                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
7848            app.persistent = true;
7849            app.maxAdj = CORE_SERVER_ADJ;
7850        }
7851        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
7852            mPersistentStartingProcesses.add(app);
7853            startProcessLocked(app, "added application", app.processName);
7854        }
7855
7856        return app;
7857    }
7858
7859    public void unhandledBack() {
7860        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
7861                "unhandledBack()");
7862
7863        synchronized(this) {
7864            int count = mHistory.size();
7865            if (DEBUG_SWITCH) Log.d(
7866                TAG, "Performing unhandledBack(): stack size = " + count);
7867            if (count > 1) {
7868                final long origId = Binder.clearCallingIdentity();
7869                finishActivityLocked((HistoryRecord)mHistory.get(count-1),
7870                        count-1, Activity.RESULT_CANCELED, null, "unhandled-back");
7871                Binder.restoreCallingIdentity(origId);
7872            }
7873        }
7874    }
7875
7876    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
7877        String name = uri.getAuthority();
7878        ContentProviderHolder cph = getContentProviderExternal(name);
7879        ParcelFileDescriptor pfd = null;
7880        if (cph != null) {
7881            // We record the binder invoker's uid in thread-local storage before
7882            // going to the content provider to open the file.  Later, in the code
7883            // that handles all permissions checks, we look for this uid and use
7884            // that rather than the Activity Manager's own uid.  The effect is that
7885            // we do the check against the caller's permissions even though it looks
7886            // to the content provider like the Activity Manager itself is making
7887            // the request.
7888            sCallerIdentity.set(new Identity(
7889                    Binder.getCallingPid(), Binder.getCallingUid()));
7890            try {
7891                pfd = cph.provider.openFile(uri, "r");
7892            } catch (FileNotFoundException e) {
7893                // do nothing; pfd will be returned null
7894            } finally {
7895                // Ensure that whatever happens, we clean up the identity state
7896                sCallerIdentity.remove();
7897            }
7898
7899            // We've got the fd now, so we're done with the provider.
7900            removeContentProviderExternal(name);
7901        } else {
7902            Log.d(TAG, "Failed to get provider for authority '" + name + "'");
7903        }
7904        return pfd;
7905    }
7906
7907    public void goingToSleep() {
7908        synchronized(this) {
7909            mSleeping = true;
7910            mWindowManager.setEventDispatching(false);
7911
7912            if (mResumedActivity != null) {
7913                pauseIfSleepingLocked();
7914            } else {
7915                Log.w(TAG, "goingToSleep with no resumed activity!");
7916            }
7917        }
7918    }
7919
7920    public boolean shutdown(int timeout) {
7921        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
7922                != PackageManager.PERMISSION_GRANTED) {
7923            throw new SecurityException("Requires permission "
7924                    + android.Manifest.permission.SHUTDOWN);
7925        }
7926
7927        boolean timedout = false;
7928
7929        synchronized(this) {
7930            mShuttingDown = true;
7931            mWindowManager.setEventDispatching(false);
7932
7933            if (mResumedActivity != null) {
7934                pauseIfSleepingLocked();
7935                final long endTime = System.currentTimeMillis() + timeout;
7936                while (mResumedActivity != null || mPausingActivity != null) {
7937                    long delay = endTime - System.currentTimeMillis();
7938                    if (delay <= 0) {
7939                        Log.w(TAG, "Activity manager shutdown timed out");
7940                        timedout = true;
7941                        break;
7942                    }
7943                    try {
7944                        this.wait();
7945                    } catch (InterruptedException e) {
7946                    }
7947                }
7948            }
7949        }
7950
7951        mUsageStatsService.shutdown();
7952        mBatteryStatsService.shutdown();
7953
7954        return timedout;
7955    }
7956
7957    void pauseIfSleepingLocked() {
7958        if (mSleeping || mShuttingDown) {
7959            if (!mGoingToSleep.isHeld()) {
7960                mGoingToSleep.acquire();
7961                if (mLaunchingActivity.isHeld()) {
7962                    mLaunchingActivity.release();
7963                    mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
7964                }
7965            }
7966
7967            // If we are not currently pausing an activity, get the current
7968            // one to pause.  If we are pausing one, we will just let that stuff
7969            // run and release the wake lock when all done.
7970            if (mPausingActivity == null) {
7971                if (DEBUG_PAUSE) Log.v(TAG, "Sleep needs to pause...");
7972                if (DEBUG_USER_LEAVING) Log.v(TAG, "Sleep => pause with userLeaving=false");
7973                startPausingLocked(false, true);
7974            }
7975        }
7976    }
7977
7978    public void wakingUp() {
7979        synchronized(this) {
7980            if (mGoingToSleep.isHeld()) {
7981                mGoingToSleep.release();
7982            }
7983            mWindowManager.setEventDispatching(true);
7984            mSleeping = false;
7985            resumeTopActivityLocked(null);
7986        }
7987    }
7988
7989    public void stopAppSwitches() {
7990        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
7991                != PackageManager.PERMISSION_GRANTED) {
7992            throw new SecurityException("Requires permission "
7993                    + android.Manifest.permission.STOP_APP_SWITCHES);
7994        }
7995
7996        synchronized(this) {
7997            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
7998                    + APP_SWITCH_DELAY_TIME;
7999            mDidAppSwitch = false;
8000            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8001            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8002            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
8003        }
8004    }
8005
8006    public void resumeAppSwitches() {
8007        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8008                != PackageManager.PERMISSION_GRANTED) {
8009            throw new SecurityException("Requires permission "
8010                    + android.Manifest.permission.STOP_APP_SWITCHES);
8011        }
8012
8013        synchronized(this) {
8014            // Note that we don't execute any pending app switches... we will
8015            // let those wait until either the timeout, or the next start
8016            // activity request.
8017            mAppSwitchesAllowedTime = 0;
8018        }
8019    }
8020
8021    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
8022            String name) {
8023        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
8024            return true;
8025        }
8026
8027        final int perm = checkComponentPermission(
8028                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
8029                callingUid, -1);
8030        if (perm == PackageManager.PERMISSION_GRANTED) {
8031            return true;
8032        }
8033
8034        Log.w(TAG, name + " request from " + callingUid + " stopped");
8035        return false;
8036    }
8037
8038    public void setDebugApp(String packageName, boolean waitForDebugger,
8039            boolean persistent) {
8040        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
8041                "setDebugApp()");
8042
8043        // Note that this is not really thread safe if there are multiple
8044        // callers into it at the same time, but that's not a situation we
8045        // care about.
8046        if (persistent) {
8047            final ContentResolver resolver = mContext.getContentResolver();
8048            Settings.System.putString(
8049                resolver, Settings.System.DEBUG_APP,
8050                packageName);
8051            Settings.System.putInt(
8052                resolver, Settings.System.WAIT_FOR_DEBUGGER,
8053                waitForDebugger ? 1 : 0);
8054        }
8055
8056        synchronized (this) {
8057            if (!persistent) {
8058                mOrigDebugApp = mDebugApp;
8059                mOrigWaitForDebugger = mWaitForDebugger;
8060            }
8061            mDebugApp = packageName;
8062            mWaitForDebugger = waitForDebugger;
8063            mDebugTransient = !persistent;
8064            if (packageName != null) {
8065                final long origId = Binder.clearCallingIdentity();
8066                forceStopPackageLocked(packageName, -1, false, false);
8067                Binder.restoreCallingIdentity(origId);
8068            }
8069        }
8070    }
8071
8072    public void setAlwaysFinish(boolean enabled) {
8073        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
8074                "setAlwaysFinish()");
8075
8076        Settings.System.putInt(
8077                mContext.getContentResolver(),
8078                Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
8079
8080        synchronized (this) {
8081            mAlwaysFinishActivities = enabled;
8082        }
8083    }
8084
8085    public void setActivityController(IActivityController controller) {
8086        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8087                "setActivityController()");
8088        synchronized (this) {
8089            mController = controller;
8090        }
8091    }
8092
8093    public boolean isUserAMonkey() {
8094        // For now the fact that there is a controller implies
8095        // we have a monkey.
8096        synchronized (this) {
8097            return mController != null;
8098        }
8099    }
8100
8101    public void registerActivityWatcher(IActivityWatcher watcher) {
8102        mWatchers.register(watcher);
8103    }
8104
8105    public void unregisterActivityWatcher(IActivityWatcher watcher) {
8106        mWatchers.unregister(watcher);
8107    }
8108
8109    public final void enterSafeMode() {
8110        synchronized(this) {
8111            // It only makes sense to do this before the system is ready
8112            // and started launching other packages.
8113            if (!mSystemReady) {
8114                try {
8115                    ActivityThread.getPackageManager().enterSafeMode();
8116                } catch (RemoteException e) {
8117                }
8118
8119                View v = LayoutInflater.from(mContext).inflate(
8120                        com.android.internal.R.layout.safe_mode, null);
8121                WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
8122                lp.type = WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY;
8123                lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
8124                lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
8125                lp.gravity = Gravity.BOTTOM | Gravity.LEFT;
8126                lp.format = v.getBackground().getOpacity();
8127                lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
8128                        | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
8129                ((WindowManager)mContext.getSystemService(
8130                        Context.WINDOW_SERVICE)).addView(v, lp);
8131            }
8132        }
8133    }
8134
8135    public void noteWakeupAlarm(IIntentSender sender) {
8136        if (!(sender instanceof PendingIntentRecord)) {
8137            return;
8138        }
8139        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8140        synchronized (stats) {
8141            if (mBatteryStatsService.isOnBattery()) {
8142                mBatteryStatsService.enforceCallingPermission();
8143                PendingIntentRecord rec = (PendingIntentRecord)sender;
8144                int MY_UID = Binder.getCallingUid();
8145                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
8146                BatteryStatsImpl.Uid.Pkg pkg =
8147                    stats.getPackageStatsLocked(uid, rec.key.packageName);
8148                pkg.incWakeupsLocked();
8149            }
8150        }
8151    }
8152
8153    public boolean killPidsForMemory(int[] pids) {
8154        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
8155            throw new SecurityException("killPidsForMemory only available to the system");
8156        }
8157
8158        // XXX Note: don't acquire main activity lock here, because the window
8159        // manager calls in with its locks held.
8160
8161        boolean killed = false;
8162        synchronized (mPidsSelfLocked) {
8163            int[] types = new int[pids.length];
8164            int worstType = 0;
8165            for (int i=0; i<pids.length; i++) {
8166                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
8167                if (proc != null) {
8168                    int type = proc.setAdj;
8169                    types[i] = type;
8170                    if (type > worstType) {
8171                        worstType = type;
8172                    }
8173                }
8174            }
8175
8176            // If the worse oom_adj is somewhere in the hidden proc LRU range,
8177            // then constrain it so we will kill all hidden procs.
8178            if (worstType < EMPTY_APP_ADJ && worstType > HIDDEN_APP_MIN_ADJ) {
8179                worstType = HIDDEN_APP_MIN_ADJ;
8180            }
8181            Log.w(TAG, "Killing processes for memory at adjustment " + worstType);
8182            for (int i=0; i<pids.length; i++) {
8183                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
8184                if (proc == null) {
8185                    continue;
8186                }
8187                int adj = proc.setAdj;
8188                if (adj >= worstType) {
8189                    Log.w(TAG, "Killing for memory: " + proc + " (adj "
8190                            + adj + ")");
8191                    EventLog.writeEvent(EventLogTags.AM_KILL_FOR_MEMORY, proc.pid,
8192                            proc.processName, adj);
8193                    killed = true;
8194                    Process.killProcess(pids[i]);
8195                }
8196            }
8197        }
8198        return killed;
8199    }
8200
8201    public void reportPss(IApplicationThread caller, int pss) {
8202        Watchdog.PssRequestor req;
8203        String name;
8204        ProcessRecord callerApp;
8205        synchronized (this) {
8206            if (caller == null) {
8207                return;
8208            }
8209            callerApp = getRecordForAppLocked(caller);
8210            if (callerApp == null) {
8211                return;
8212            }
8213            callerApp.lastPss = pss;
8214            req = callerApp;
8215            name = callerApp.processName;
8216        }
8217        Watchdog.getInstance().reportPss(req, name, pss);
8218        if (!callerApp.persistent) {
8219            removeRequestedPss(callerApp);
8220        }
8221    }
8222
8223    public void requestPss(Runnable completeCallback) {
8224        ArrayList<ProcessRecord> procs;
8225        synchronized (this) {
8226            mRequestPssCallback = completeCallback;
8227            mRequestPssList.clear();
8228            for (int i=mLruProcesses.size()-1; i>=0; i--) {
8229                ProcessRecord proc = mLruProcesses.get(i);
8230                if (!proc.persistent) {
8231                    mRequestPssList.add(proc);
8232                }
8233            }
8234            procs = new ArrayList<ProcessRecord>(mRequestPssList);
8235        }
8236
8237        int oldPri = Process.getThreadPriority(Process.myTid());
8238        Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
8239        for (int i=procs.size()-1; i>=0; i--) {
8240            ProcessRecord proc = procs.get(i);
8241            proc.lastPss = 0;
8242            proc.requestPss();
8243        }
8244        Process.setThreadPriority(oldPri);
8245    }
8246
8247    void removeRequestedPss(ProcessRecord proc) {
8248        Runnable callback = null;
8249        synchronized (this) {
8250            if (mRequestPssList.remove(proc)) {
8251                if (mRequestPssList.size() == 0) {
8252                    callback = mRequestPssCallback;
8253                    mRequestPssCallback = null;
8254                }
8255            }
8256        }
8257
8258        if (callback != null) {
8259            callback.run();
8260        }
8261    }
8262
8263    public void collectPss(Watchdog.PssStats stats) {
8264        stats.mEmptyPss = 0;
8265        stats.mEmptyCount = 0;
8266        stats.mBackgroundPss = 0;
8267        stats.mBackgroundCount = 0;
8268        stats.mServicePss = 0;
8269        stats.mServiceCount = 0;
8270        stats.mVisiblePss = 0;
8271        stats.mVisibleCount = 0;
8272        stats.mForegroundPss = 0;
8273        stats.mForegroundCount = 0;
8274        stats.mNoPssCount = 0;
8275        synchronized (this) {
8276            int i;
8277            int NPD = mProcDeaths.length < stats.mProcDeaths.length
8278                    ? mProcDeaths.length : stats.mProcDeaths.length;
8279            int aggr = 0;
8280            for (i=0; i<NPD; i++) {
8281                aggr += mProcDeaths[i];
8282                stats.mProcDeaths[i] = aggr;
8283            }
8284            while (i<stats.mProcDeaths.length) {
8285                stats.mProcDeaths[i] = 0;
8286                i++;
8287            }
8288
8289            for (i=mLruProcesses.size()-1; i>=0; i--) {
8290                ProcessRecord proc = mLruProcesses.get(i);
8291                if (proc.persistent) {
8292                    continue;
8293                }
8294                //Log.i(TAG, "Proc " + proc + ": pss=" + proc.lastPss);
8295                if (proc.lastPss == 0) {
8296                    stats.mNoPssCount++;
8297                    continue;
8298                }
8299                if (proc.setAdj >= HIDDEN_APP_MIN_ADJ) {
8300                    if (proc.empty) {
8301                        stats.mEmptyPss += proc.lastPss;
8302                        stats.mEmptyCount++;
8303                    } else {
8304                        stats.mBackgroundPss += proc.lastPss;
8305                        stats.mBackgroundCount++;
8306                    }
8307                } else if (proc.setAdj >= VISIBLE_APP_ADJ) {
8308                    stats.mVisiblePss += proc.lastPss;
8309                    stats.mVisibleCount++;
8310                } else {
8311                    stats.mForegroundPss += proc.lastPss;
8312                    stats.mForegroundCount++;
8313                }
8314            }
8315        }
8316    }
8317
8318    public final void startRunning(String pkg, String cls, String action,
8319            String data) {
8320        synchronized(this) {
8321            if (mStartRunning) {
8322                return;
8323            }
8324            mStartRunning = true;
8325            mTopComponent = pkg != null && cls != null
8326                    ? new ComponentName(pkg, cls) : null;
8327            mTopAction = action != null ? action : Intent.ACTION_MAIN;
8328            mTopData = data;
8329            if (!mSystemReady) {
8330                return;
8331            }
8332        }
8333
8334        systemReady(null);
8335    }
8336
8337    private void retrieveSettings() {
8338        final ContentResolver resolver = mContext.getContentResolver();
8339        String debugApp = Settings.System.getString(
8340            resolver, Settings.System.DEBUG_APP);
8341        boolean waitForDebugger = Settings.System.getInt(
8342            resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0;
8343        boolean alwaysFinishActivities = Settings.System.getInt(
8344            resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
8345
8346        Configuration configuration = new Configuration();
8347        Settings.System.getConfiguration(resolver, configuration);
8348
8349        synchronized (this) {
8350            mDebugApp = mOrigDebugApp = debugApp;
8351            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
8352            mAlwaysFinishActivities = alwaysFinishActivities;
8353            // This happens before any activities are started, so we can
8354            // change mConfiguration in-place.
8355            mConfiguration.updateFrom(configuration);
8356            if (DEBUG_CONFIGURATION) Log.v(TAG, "Initial config: " + mConfiguration);
8357        }
8358    }
8359
8360    public boolean testIsSystemReady() {
8361        // no need to synchronize(this) just to read & return the value
8362        return mSystemReady;
8363    }
8364
8365    public void systemReady(final Runnable goingCallback) {
8366        // In the simulator, startRunning will never have been called, which
8367        // normally sets a few crucial variables. Do it here instead.
8368        if (!Process.supportsProcesses()) {
8369            mStartRunning = true;
8370            mTopAction = Intent.ACTION_MAIN;
8371        }
8372
8373        synchronized(this) {
8374            if (mSystemReady) {
8375                if (goingCallback != null) goingCallback.run();
8376                return;
8377            }
8378
8379            // Check to see if there are any update receivers to run.
8380            if (!mDidUpdate) {
8381                if (mWaitingUpdate) {
8382                    return;
8383                }
8384                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
8385                List<ResolveInfo> ris = null;
8386                try {
8387                    ris = ActivityThread.getPackageManager().queryIntentReceivers(
8388                                intent, null, 0);
8389                } catch (RemoteException e) {
8390                }
8391                if (ris != null) {
8392                    for (int i=ris.size()-1; i>=0; i--) {
8393                        if ((ris.get(i).activityInfo.applicationInfo.flags
8394                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
8395                            ris.remove(i);
8396                        }
8397                    }
8398                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
8399                    for (int i=0; i<ris.size(); i++) {
8400                        ActivityInfo ai = ris.get(i).activityInfo;
8401                        intent.setComponent(new ComponentName(ai.packageName, ai.name));
8402                        IIntentReceiver finisher = null;
8403                        if (i == ris.size()-1) {
8404                            finisher = new IIntentReceiver.Stub() {
8405                                public void performReceive(Intent intent, int resultCode,
8406                                        String data, Bundle extras, boolean ordered,
8407                                        boolean sticky)
8408                                        throws RemoteException {
8409                                    synchronized (ActivityManagerService.this) {
8410                                        mDidUpdate = true;
8411                                    }
8412                                    systemReady(goingCallback);
8413                                }
8414                            };
8415                        }
8416                        Log.i(TAG, "Sending system update to: " + intent.getComponent());
8417                        broadcastIntentLocked(null, null, intent, null, finisher,
8418                                0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID);
8419                        if (finisher != null) {
8420                            mWaitingUpdate = true;
8421                        }
8422                    }
8423                }
8424                if (mWaitingUpdate) {
8425                    return;
8426                }
8427                mDidUpdate = true;
8428            }
8429
8430            mSystemReady = true;
8431            if (!mStartRunning) {
8432                return;
8433            }
8434        }
8435
8436        ArrayList<ProcessRecord> procsToKill = null;
8437        synchronized(mPidsSelfLocked) {
8438            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
8439                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
8440                if (!isAllowedWhileBooting(proc.info)){
8441                    if (procsToKill == null) {
8442                        procsToKill = new ArrayList<ProcessRecord>();
8443                    }
8444                    procsToKill.add(proc);
8445                }
8446            }
8447        }
8448
8449        if (procsToKill != null) {
8450            synchronized(this) {
8451                for (int i=procsToKill.size()-1; i>=0; i--) {
8452                    ProcessRecord proc = procsToKill.get(i);
8453                    Log.i(TAG, "Removing system update proc: " + proc);
8454                    removeProcessLocked(proc, true);
8455                }
8456            }
8457        }
8458
8459        Log.i(TAG, "System now ready");
8460        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
8461            SystemClock.uptimeMillis());
8462
8463        synchronized(this) {
8464            // Make sure we have no pre-ready processes sitting around.
8465
8466            if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
8467                ResolveInfo ri = mContext.getPackageManager()
8468                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
8469                                STOCK_PM_FLAGS);
8470                CharSequence errorMsg = null;
8471                if (ri != null) {
8472                    ActivityInfo ai = ri.activityInfo;
8473                    ApplicationInfo app = ai.applicationInfo;
8474                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
8475                        mTopAction = Intent.ACTION_FACTORY_TEST;
8476                        mTopData = null;
8477                        mTopComponent = new ComponentName(app.packageName,
8478                                ai.name);
8479                    } else {
8480                        errorMsg = mContext.getResources().getText(
8481                                com.android.internal.R.string.factorytest_not_system);
8482                    }
8483                } else {
8484                    errorMsg = mContext.getResources().getText(
8485                            com.android.internal.R.string.factorytest_no_action);
8486                }
8487                if (errorMsg != null) {
8488                    mTopAction = null;
8489                    mTopData = null;
8490                    mTopComponent = null;
8491                    Message msg = Message.obtain();
8492                    msg.what = SHOW_FACTORY_ERROR_MSG;
8493                    msg.getData().putCharSequence("msg", errorMsg);
8494                    mHandler.sendMessage(msg);
8495                }
8496            }
8497        }
8498
8499        retrieveSettings();
8500
8501        if (goingCallback != null) goingCallback.run();
8502
8503        synchronized (this) {
8504            if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
8505                try {
8506                    List apps = ActivityThread.getPackageManager().
8507                        getPersistentApplications(STOCK_PM_FLAGS);
8508                    if (apps != null) {
8509                        int N = apps.size();
8510                        int i;
8511                        for (i=0; i<N; i++) {
8512                            ApplicationInfo info
8513                                = (ApplicationInfo)apps.get(i);
8514                            if (info != null &&
8515                                    !info.packageName.equals("android")) {
8516                                addAppLocked(info);
8517                            }
8518                        }
8519                    }
8520                } catch (RemoteException ex) {
8521                    // pm is in same process, this will never happen.
8522                }
8523            }
8524
8525            // Start up initial activity.
8526            mBooting = true;
8527
8528            try {
8529                if (ActivityThread.getPackageManager().hasSystemUidErrors()) {
8530                    Message msg = Message.obtain();
8531                    msg.what = SHOW_UID_ERROR_MSG;
8532                    mHandler.sendMessage(msg);
8533                }
8534            } catch (RemoteException e) {
8535            }
8536
8537            resumeTopActivityLocked(null);
8538        }
8539    }
8540
8541    private boolean makeAppCrashingLocked(ProcessRecord app,
8542            String shortMsg, String longMsg, String stackTrace) {
8543        app.crashing = true;
8544        app.crashingReport = generateProcessError(app,
8545                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
8546        startAppProblemLocked(app);
8547        app.stopFreezingAllLocked();
8548        return handleAppCrashLocked(app);
8549    }
8550
8551    private ComponentName getErrorReportReceiver(ProcessRecord app) {
8552        // check if error reporting is enabled in secure settings
8553        int enabled = Settings.Secure.getInt(mContext.getContentResolver(),
8554                Settings.Secure.SEND_ACTION_APP_ERROR, 0);
8555        if (enabled == 0) {
8556            return null;
8557        }
8558
8559        IPackageManager pm = ActivityThread.getPackageManager();
8560
8561        try {
8562            // look for receiver in the installer package
8563            String candidate = pm.getInstallerPackageName(app.info.packageName);
8564            ComponentName result = getErrorReportReceiver(pm, app.info.packageName, candidate);
8565            if (result != null) {
8566                return result;
8567            }
8568
8569            // if the error app is on the system image, look for system apps
8570            // error receiver
8571            if ((app.info.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
8572                candidate = SystemProperties.get(SYSTEM_APPS_ERROR_RECEIVER_PROPERTY);
8573                result = getErrorReportReceiver(pm, app.info.packageName, candidate);
8574                if (result != null) {
8575                    return result;
8576                }
8577            }
8578
8579            // if there is a default receiver, try that
8580            candidate = SystemProperties.get(DEFAULT_ERROR_RECEIVER_PROPERTY);
8581            return getErrorReportReceiver(pm, app.info.packageName, candidate);
8582        } catch (RemoteException e) {
8583            // should not happen
8584            Log.e(TAG, "error talking to PackageManager", e);
8585            return null;
8586        }
8587    }
8588
8589    /**
8590     * Return activity in receiverPackage that handles ACTION_APP_ERROR.
8591     *
8592     * @param pm PackageManager isntance
8593     * @param errorPackage package which caused the error
8594     * @param receiverPackage candidate package to receive the error
8595     * @return activity component within receiverPackage which handles
8596     * ACTION_APP_ERROR, or null if not found
8597     */
8598    private ComponentName getErrorReportReceiver(IPackageManager pm, String errorPackage,
8599            String receiverPackage) throws RemoteException {
8600        if (receiverPackage == null || receiverPackage.length() == 0) {
8601            return null;
8602        }
8603
8604        // break the loop if it's the error report receiver package that crashed
8605        if (receiverPackage.equals(errorPackage)) {
8606            return null;
8607        }
8608
8609        Intent intent = new Intent(Intent.ACTION_APP_ERROR);
8610        intent.setPackage(receiverPackage);
8611        ResolveInfo info = pm.resolveIntent(intent, null, 0);
8612        if (info == null || info.activityInfo == null) {
8613            return null;
8614        }
8615        return new ComponentName(receiverPackage, info.activityInfo.name);
8616    }
8617
8618    private void makeAppNotRespondingLocked(ProcessRecord app,
8619            String activity, String shortMsg, String longMsg) {
8620        app.notResponding = true;
8621        app.notRespondingReport = generateProcessError(app,
8622                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
8623                activity, shortMsg, longMsg, null);
8624        startAppProblemLocked(app);
8625        app.stopFreezingAllLocked();
8626    }
8627
8628    /**
8629     * Generate a process error record, suitable for attachment to a ProcessRecord.
8630     *
8631     * @param app The ProcessRecord in which the error occurred.
8632     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
8633     *                      ActivityManager.AppErrorStateInfo
8634     * @param activity The activity associated with the crash, if known.
8635     * @param shortMsg Short message describing the crash.
8636     * @param longMsg Long message describing the crash.
8637     * @param stackTrace Full crash stack trace, may be null.
8638     *
8639     * @return Returns a fully-formed AppErrorStateInfo record.
8640     */
8641    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
8642            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
8643        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
8644
8645        report.condition = condition;
8646        report.processName = app.processName;
8647        report.pid = app.pid;
8648        report.uid = app.info.uid;
8649        report.tag = activity;
8650        report.shortMsg = shortMsg;
8651        report.longMsg = longMsg;
8652        report.stackTrace = stackTrace;
8653
8654        return report;
8655    }
8656
8657    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
8658        synchronized (this) {
8659            app.crashing = false;
8660            app.crashingReport = null;
8661            app.notResponding = false;
8662            app.notRespondingReport = null;
8663            if (app.anrDialog == fromDialog) {
8664                app.anrDialog = null;
8665            }
8666            if (app.waitDialog == fromDialog) {
8667                app.waitDialog = null;
8668            }
8669            if (app.pid > 0 && app.pid != MY_PID) {
8670                handleAppCrashLocked(app);
8671                Log.i(ActivityManagerService.TAG, "Killing process "
8672                        + app.processName
8673                        + " (pid=" + app.pid + ") at user's request");
8674                Process.killProcess(app.pid);
8675            }
8676        }
8677    }
8678
8679    private boolean handleAppCrashLocked(ProcessRecord app) {
8680        long now = SystemClock.uptimeMillis();
8681
8682        Long crashTime = mProcessCrashTimes.get(app.info.processName,
8683                app.info.uid);
8684        if (crashTime != null && now < crashTime+MIN_CRASH_INTERVAL) {
8685            // This process loses!
8686            Log.w(TAG, "Process " + app.info.processName
8687                    + " has crashed too many times: killing!");
8688            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
8689                    app.info.processName, app.info.uid);
8690            killServicesLocked(app, false);
8691            for (int i=mHistory.size()-1; i>=0; i--) {
8692                HistoryRecord r = (HistoryRecord)mHistory.get(i);
8693                if (r.app == app) {
8694                    Log.w(TAG, "  Force finishing activity "
8695                        + r.intent.getComponent().flattenToShortString());
8696                    finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed");
8697                }
8698            }
8699            if (!app.persistent) {
8700                // We don't want to start this process again until the user
8701                // explicitly does so...  but for persistent process, we really
8702                // need to keep it running.  If a persistent process is actually
8703                // repeatedly crashing, then badness for everyone.
8704                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.info.uid,
8705                        app.info.processName);
8706                mBadProcesses.put(app.info.processName, app.info.uid, now);
8707                app.bad = true;
8708                mProcessCrashTimes.remove(app.info.processName, app.info.uid);
8709                app.removed = true;
8710                removeProcessLocked(app, false);
8711                return false;
8712            }
8713        }
8714
8715        // Bump up the crash count of any services currently running in the proc.
8716        if (app.services.size() != 0) {
8717            // Any services running in the application need to be placed
8718            // back in the pending list.
8719            Iterator it = app.services.iterator();
8720            while (it.hasNext()) {
8721                ServiceRecord sr = (ServiceRecord)it.next();
8722                sr.crashCount++;
8723            }
8724        }
8725
8726        mProcessCrashTimes.put(app.info.processName, app.info.uid, now);
8727        return true;
8728    }
8729
8730    void startAppProblemLocked(ProcessRecord app) {
8731        app.errorReportReceiver = getErrorReportReceiver(app);
8732        skipCurrentReceiverLocked(app);
8733    }
8734
8735    void skipCurrentReceiverLocked(ProcessRecord app) {
8736        boolean reschedule = false;
8737        BroadcastRecord r = app.curReceiver;
8738        if (r != null) {
8739            // The current broadcast is waiting for this app's receiver
8740            // to be finished.  Looks like that's not going to happen, so
8741            // let the broadcast continue.
8742            logBroadcastReceiverDiscard(r);
8743            finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
8744                    r.resultExtras, r.resultAbort, true);
8745            reschedule = true;
8746        }
8747        r = mPendingBroadcast;
8748        if (r != null && r.curApp == app) {
8749            if (DEBUG_BROADCAST) Log.v(TAG,
8750                    "skip & discard pending app " + r);
8751            logBroadcastReceiverDiscard(r);
8752            finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
8753                    r.resultExtras, r.resultAbort, true);
8754            reschedule = true;
8755        }
8756        if (reschedule) {
8757            scheduleBroadcastsLocked();
8758        }
8759    }
8760
8761    /**
8762     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
8763     * The application process will exit immediately after this call returns.
8764     * @param app object of the crashing app, null for the system server
8765     * @param crashInfo describing the exception
8766     */
8767    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
8768        ProcessRecord r = findAppProcess(app);
8769
8770        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
8771                app == null ? "system" : (r == null ? "unknown" : r.processName),
8772                r == null ? -1 : r.info.flags,
8773                crashInfo.exceptionClassName,
8774                crashInfo.exceptionMessage,
8775                crashInfo.throwFileName,
8776                crashInfo.throwLineNumber);
8777
8778        addErrorToDropBox("crash", r, null, null, null, null, null, crashInfo);
8779
8780        crashApplication(r, crashInfo);
8781    }
8782
8783    /**
8784     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
8785     * @param app object of the crashing app, null for the system server
8786     * @param tag reported by the caller
8787     * @param crashInfo describing the context of the error
8788     * @return true if the process should exit immediately (WTF is fatal)
8789     */
8790    public boolean handleApplicationWtf(IBinder app, String tag,
8791            ApplicationErrorReport.CrashInfo crashInfo) {
8792        ProcessRecord r = findAppProcess(app);
8793
8794        EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(),
8795                app == null ? "system" : (r == null ? "unknown" : r.processName),
8796                r == null ? -1 : r.info.flags,
8797                tag, crashInfo.exceptionMessage);
8798
8799        addErrorToDropBox("wtf", r, null, null, tag, null, null, crashInfo);
8800
8801        if (Settings.Secure.getInt(mContext.getContentResolver(),
8802                Settings.Secure.WTF_IS_FATAL, 0) != 0) {
8803            crashApplication(r, crashInfo);
8804            return true;
8805        } else {
8806            return false;
8807        }
8808    }
8809
8810    /**
8811     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
8812     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
8813     */
8814    private ProcessRecord findAppProcess(IBinder app) {
8815        if (app == null) {
8816            return null;
8817        }
8818
8819        synchronized (this) {
8820            for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
8821                final int NA = apps.size();
8822                for (int ia=0; ia<NA; ia++) {
8823                    ProcessRecord p = apps.valueAt(ia);
8824                    if (p.thread != null && p.thread.asBinder() == app) {
8825                        return p;
8826                    }
8827                }
8828            }
8829
8830            Log.w(TAG, "Can't find mystery application: " + app);
8831            return null;
8832        }
8833    }
8834
8835    /**
8836     * Write a description of an error (crash, WTF, ANR) to the drop box.
8837     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
8838     * @param process which caused the error, null means the system server
8839     * @param activity which triggered the error, null if unknown
8840     * @param parent activity related to the error, null if unknown
8841     * @param subject line related to the error, null if absent
8842     * @param report in long form describing the error, null if absent
8843     * @param logFile to include in the report, null if none
8844     * @param crashInfo giving an application stack trace, null if absent
8845     */
8846    private void addErrorToDropBox(String eventType,
8847            ProcessRecord process, HistoryRecord activity, HistoryRecord parent,
8848            String subject, String report, File logFile,
8849            ApplicationErrorReport.CrashInfo crashInfo) {
8850        String dropboxTag;
8851        if (process == null || process.pid == MY_PID) {
8852            dropboxTag = "system_server_" + eventType;
8853        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
8854            dropboxTag = "system_app_" + eventType;
8855        } else {
8856            dropboxTag = "data_app_" + eventType;
8857        }
8858
8859        DropBoxManager dbox = (DropBoxManager) mContext.getSystemService(Context.DROPBOX_SERVICE);
8860        if (dbox != null && dbox.isTagEnabled(dropboxTag)) {
8861            StringBuilder sb = new StringBuilder(1024);
8862            if (process == null || process.pid == MY_PID) {
8863                sb.append("Process: system_server\n");
8864            } else {
8865                sb.append("Process: ").append(process.processName).append("\n");
8866            }
8867            if (process != null) {
8868                int flags = process.info.flags;
8869                IPackageManager pm = ActivityThread.getPackageManager();
8870                sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
8871                for (String pkg : process.pkgList) {
8872                    sb.append("Package: ").append(pkg);
8873                    try {
8874                        PackageInfo pi = pm.getPackageInfo(pkg, 0);
8875                        if (pi != null) {
8876                            sb.append(" v").append(pi.versionCode);
8877                            if (pi.versionName != null) {
8878                                sb.append(" (").append(pi.versionName).append(")");
8879                            }
8880                        }
8881                    } catch (RemoteException e) {
8882                        Log.e(TAG, "Error getting package info: " + pkg, e);
8883                    }
8884                    sb.append("\n");
8885                }
8886            }
8887            if (activity != null) {
8888                sb.append("Activity: ").append(activity.shortComponentName).append("\n");
8889            }
8890            if (parent != null && parent.app != null && parent.app.pid != process.pid) {
8891                sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
8892            }
8893            if (parent != null && parent != activity) {
8894                sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
8895            }
8896            if (subject != null) {
8897                sb.append("Subject: ").append(subject).append("\n");
8898            }
8899            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
8900            sb.append("\n");
8901            if (report != null) {
8902                sb.append(report);
8903            }
8904            if (logFile != null) {
8905                try {
8906                    sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]"));
8907                } catch (IOException e) {
8908                    Log.e(TAG, "Error reading " + logFile, e);
8909                }
8910            }
8911            if (crashInfo != null && crashInfo.stackTrace != null) {
8912                sb.append(crashInfo.stackTrace);
8913            }
8914            dbox.addText(dropboxTag, sb.toString());
8915        }
8916    }
8917
8918    /**
8919     * Bring up the "unexpected error" dialog box for a crashing app.
8920     * Deal with edge cases (intercepts from instrumented applications,
8921     * ActivityController, error intent receivers, that sort of thing).
8922     * @param r the application crashing
8923     * @param crashInfo describing the failure
8924     */
8925    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
8926        long timeMillis = System.currentTimeMillis();
8927        String shortMsg = crashInfo.exceptionClassName;
8928        String longMsg = crashInfo.exceptionMessage;
8929        String stackTrace = crashInfo.stackTrace;
8930        if (shortMsg != null && longMsg != null) {
8931            longMsg = shortMsg + ": " + longMsg;
8932        } else if (shortMsg != null) {
8933            longMsg = shortMsg;
8934        }
8935
8936        AppErrorResult result = new AppErrorResult();
8937        synchronized (this) {
8938            if (mController != null) {
8939                try {
8940                    String name = r != null ? r.processName : null;
8941                    int pid = r != null ? r.pid : Binder.getCallingPid();
8942                    if (!mController.appCrashed(name, pid,
8943                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
8944                        Log.w(TAG, "Force-killing crashed app " + name
8945                                + " at watcher's request");
8946                        Process.killProcess(pid);
8947                        return;
8948                    }
8949                } catch (RemoteException e) {
8950                    mController = null;
8951                }
8952            }
8953
8954            final long origId = Binder.clearCallingIdentity();
8955
8956            // If this process is running instrumentation, finish it.
8957            if (r != null && r.instrumentationClass != null) {
8958                Log.w(TAG, "Error in app " + r.processName
8959                      + " running instrumentation " + r.instrumentationClass + ":");
8960                if (shortMsg != null) Log.w(TAG, "  " + shortMsg);
8961                if (longMsg != null) Log.w(TAG, "  " + longMsg);
8962                Bundle info = new Bundle();
8963                info.putString("shortMsg", shortMsg);
8964                info.putString("longMsg", longMsg);
8965                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
8966                Binder.restoreCallingIdentity(origId);
8967                return;
8968            }
8969
8970            // If we can't identify the process or it's already exceeded its crash quota,
8971            // quit right away without showing a crash dialog.
8972            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
8973                Binder.restoreCallingIdentity(origId);
8974                return;
8975            }
8976
8977            Message msg = Message.obtain();
8978            msg.what = SHOW_ERROR_MSG;
8979            HashMap data = new HashMap();
8980            data.put("result", result);
8981            data.put("app", r);
8982            msg.obj = data;
8983            mHandler.sendMessage(msg);
8984
8985            Binder.restoreCallingIdentity(origId);
8986        }
8987
8988        int res = result.get();
8989
8990        Intent appErrorIntent = null;
8991        synchronized (this) {
8992            if (r != null) {
8993                mProcessCrashTimes.put(r.info.processName, r.info.uid,
8994                        SystemClock.uptimeMillis());
8995            }
8996            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
8997                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
8998            }
8999        }
9000
9001        if (appErrorIntent != null) {
9002            try {
9003                mContext.startActivity(appErrorIntent);
9004            } catch (ActivityNotFoundException e) {
9005                Log.w(TAG, "bug report receiver dissappeared", e);
9006            }
9007        }
9008    }
9009
9010    Intent createAppErrorIntentLocked(ProcessRecord r,
9011            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
9012        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
9013        if (report == null) {
9014            return null;
9015        }
9016        Intent result = new Intent(Intent.ACTION_APP_ERROR);
9017        result.setComponent(r.errorReportReceiver);
9018        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
9019        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
9020        return result;
9021    }
9022
9023    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
9024            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
9025        if (r.errorReportReceiver == null) {
9026            return null;
9027        }
9028
9029        if (!r.crashing && !r.notResponding) {
9030            return null;
9031        }
9032
9033        ApplicationErrorReport report = new ApplicationErrorReport();
9034        report.packageName = r.info.packageName;
9035        report.installerPackageName = r.errorReportReceiver.getPackageName();
9036        report.processName = r.processName;
9037        report.time = timeMillis;
9038        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
9039
9040        if (r.crashing) {
9041            report.type = ApplicationErrorReport.TYPE_CRASH;
9042            report.crashInfo = crashInfo;
9043        } else if (r.notResponding) {
9044            report.type = ApplicationErrorReport.TYPE_ANR;
9045            report.anrInfo = new ApplicationErrorReport.AnrInfo();
9046
9047            report.anrInfo.activity = r.notRespondingReport.tag;
9048            report.anrInfo.cause = r.notRespondingReport.shortMsg;
9049            report.anrInfo.info = r.notRespondingReport.longMsg;
9050        }
9051
9052        return report;
9053    }
9054
9055    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
9056        // assume our apps are happy - lazy create the list
9057        List<ActivityManager.ProcessErrorStateInfo> errList = null;
9058
9059        synchronized (this) {
9060
9061            // iterate across all processes
9062            for (int i=mLruProcesses.size()-1; i>=0; i--) {
9063                ProcessRecord app = mLruProcesses.get(i);
9064                if ((app.thread != null) && (app.crashing || app.notResponding)) {
9065                    // This one's in trouble, so we'll generate a report for it
9066                    // crashes are higher priority (in case there's a crash *and* an anr)
9067                    ActivityManager.ProcessErrorStateInfo report = null;
9068                    if (app.crashing) {
9069                        report = app.crashingReport;
9070                    } else if (app.notResponding) {
9071                        report = app.notRespondingReport;
9072                    }
9073
9074                    if (report != null) {
9075                        if (errList == null) {
9076                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
9077                        }
9078                        errList.add(report);
9079                    } else {
9080                        Log.w(TAG, "Missing app error report, app = " + app.processName +
9081                                " crashing = " + app.crashing +
9082                                " notResponding = " + app.notResponding);
9083                    }
9084                }
9085            }
9086        }
9087
9088        return errList;
9089    }
9090
9091    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
9092        // Lazy instantiation of list
9093        List<ActivityManager.RunningAppProcessInfo> runList = null;
9094        synchronized (this) {
9095            // Iterate across all processes
9096            for (int i=mLruProcesses.size()-1; i>=0; i--) {
9097                ProcessRecord app = mLruProcesses.get(i);
9098                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
9099                    // Generate process state info for running application
9100                    ActivityManager.RunningAppProcessInfo currApp =
9101                        new ActivityManager.RunningAppProcessInfo(app.processName,
9102                                app.pid, app.getPackageList());
9103                    currApp.uid = app.info.uid;
9104                    int adj = app.curAdj;
9105                    if (adj >= EMPTY_APP_ADJ) {
9106                        currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_EMPTY;
9107                    } else if (adj >= HIDDEN_APP_MIN_ADJ) {
9108                        currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
9109                        currApp.lru = adj - HIDDEN_APP_MIN_ADJ + 1;
9110                    } else if (adj >= HOME_APP_ADJ) {
9111                        currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
9112                        currApp.lru = 0;
9113                    } else if (adj >= SECONDARY_SERVER_ADJ) {
9114                        currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
9115                    } else if (adj >= VISIBLE_APP_ADJ) {
9116                        currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
9117                    } else {
9118                        currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
9119                    }
9120                    currApp.importanceReasonCode = app.adjTypeCode;
9121                    if (app.adjSource instanceof ProcessRecord) {
9122                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
9123                    } else if (app.adjSource instanceof HistoryRecord) {
9124                        HistoryRecord r = (HistoryRecord)app.adjSource;
9125                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
9126                    }
9127                    if (app.adjTarget instanceof ComponentName) {
9128                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
9129                    }
9130                    //Log.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
9131                    //        + " lru=" + currApp.lru);
9132                    if (runList == null) {
9133                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
9134                    }
9135                    runList.add(currApp);
9136                }
9137            }
9138        }
9139        return runList;
9140    }
9141
9142    @Override
9143    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
9144        if (checkCallingPermission(android.Manifest.permission.DUMP)
9145                != PackageManager.PERMISSION_GRANTED) {
9146            pw.println("Permission Denial: can't dump ActivityManager from from pid="
9147                    + Binder.getCallingPid()
9148                    + ", uid=" + Binder.getCallingUid()
9149                    + " without permission "
9150                    + android.Manifest.permission.DUMP);
9151            return;
9152        }
9153
9154        boolean dumpAll = false;
9155
9156        int opti = 0;
9157        while (opti < args.length) {
9158            String opt = args[opti];
9159            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
9160                break;
9161            }
9162            opti++;
9163            if ("-a".equals(opt)) {
9164                dumpAll = true;
9165            } else if ("-h".equals(opt)) {
9166                pw.println("Activity manager dump options:");
9167                pw.println("  [-a] [h- [cmd] ...");
9168                pw.println("  cmd may be one of:");
9169                pw.println("    activities: activity stack state");
9170                pw.println("    broadcasts: broadcast state");
9171                pw.println("    intents: pending intent state");
9172                pw.println("    processes: process state");
9173                pw.println("    providers: content provider state");
9174                pw.println("    services: service state");
9175                pw.println("    service [name]: service client-side state");
9176                return;
9177            } else {
9178                pw.println("Unknown argument: " + opt + "; use -h for help");
9179            }
9180        }
9181
9182        // Is the caller requesting to dump a particular piece of data?
9183        if (opti < args.length) {
9184            String cmd = args[opti];
9185            opti++;
9186            if ("activities".equals(cmd) || "a".equals(cmd)) {
9187                synchronized (this) {
9188                    dumpActivitiesLocked(fd, pw, args, opti, true, true);
9189                }
9190                return;
9191            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
9192                synchronized (this) {
9193                    dumpBroadcastsLocked(fd, pw, args, opti, true);
9194                }
9195                return;
9196            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
9197                synchronized (this) {
9198                    dumpPendingIntentsLocked(fd, pw, args, opti, true);
9199                }
9200                return;
9201            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
9202                synchronized (this) {
9203                    dumpProcessesLocked(fd, pw, args, opti, true);
9204                }
9205                return;
9206            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
9207                synchronized (this) {
9208                    dumpProvidersLocked(fd, pw, args, opti, true);
9209                }
9210                return;
9211            } else if ("service".equals(cmd)) {
9212                dumpService(fd, pw, args, opti, true);
9213                return;
9214            } else if ("services".equals(cmd) || "s".equals(cmd)) {
9215                synchronized (this) {
9216                    dumpServicesLocked(fd, pw, args, opti, true);
9217                }
9218                return;
9219            }
9220        }
9221
9222        // No piece of data specified, dump everything.
9223        synchronized (this) {
9224            boolean needSep;
9225            if (dumpAll) {
9226                pw.println("Providers in Current Activity Manager State:");
9227            }
9228            needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll);
9229            if (needSep) {
9230                pw.println(" ");
9231            }
9232            if (dumpAll) {
9233                pw.println("-------------------------------------------------------------------------------");
9234                pw.println("Broadcasts in Current Activity Manager State:");
9235            }
9236            needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll);
9237            if (needSep) {
9238                pw.println(" ");
9239            }
9240            if (dumpAll) {
9241                pw.println("-------------------------------------------------------------------------------");
9242                pw.println("Services in Current Activity Manager State:");
9243            }
9244            needSep = dumpServicesLocked(fd, pw, args, opti, dumpAll);
9245            if (needSep) {
9246                pw.println(" ");
9247            }
9248            if (dumpAll) {
9249                pw.println("-------------------------------------------------------------------------------");
9250                pw.println("PendingIntents in Current Activity Manager State:");
9251            }
9252            needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll);
9253            if (needSep) {
9254                pw.println(" ");
9255            }
9256            if (dumpAll) {
9257                pw.println("-------------------------------------------------------------------------------");
9258                pw.println("Activities in Current Activity Manager State:");
9259            }
9260            needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, !dumpAll);
9261            if (needSep) {
9262                pw.println(" ");
9263            }
9264            if (dumpAll) {
9265                pw.println("-------------------------------------------------------------------------------");
9266                pw.println("Processes in Current Activity Manager State:");
9267            }
9268            dumpProcessesLocked(fd, pw, args, opti, dumpAll);
9269        }
9270    }
9271
9272    boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9273            int opti, boolean dumpAll, boolean needHeader) {
9274        if (needHeader) {
9275            pw.println("  Activity stack:");
9276        }
9277        dumpHistoryList(pw, mHistory, "  ", "Hist", true);
9278        pw.println(" ");
9279        pw.println("  Running activities (most recent first):");
9280        dumpHistoryList(pw, mLRUActivities, "  ", "Run", false);
9281        if (mWaitingVisibleActivities.size() > 0) {
9282            pw.println(" ");
9283            pw.println("  Activities waiting for another to become visible:");
9284            dumpHistoryList(pw, mWaitingVisibleActivities, "  ", "Wait", false);
9285        }
9286        if (mStoppingActivities.size() > 0) {
9287            pw.println(" ");
9288            pw.println("  Activities waiting to stop:");
9289            dumpHistoryList(pw, mStoppingActivities, "  ", "Stop", false);
9290        }
9291        if (mFinishingActivities.size() > 0) {
9292            pw.println(" ");
9293            pw.println("  Activities waiting to finish:");
9294            dumpHistoryList(pw, mFinishingActivities, "  ", "Fin", false);
9295        }
9296
9297        pw.println(" ");
9298        pw.println("  mPausingActivity: " + mPausingActivity);
9299        pw.println("  mResumedActivity: " + mResumedActivity);
9300        pw.println("  mFocusedActivity: " + mFocusedActivity);
9301        pw.println("  mLastPausedActivity: " + mLastPausedActivity);
9302
9303        if (dumpAll && mRecentTasks.size() > 0) {
9304            pw.println(" ");
9305            pw.println("Recent tasks in Current Activity Manager State:");
9306
9307            final int N = mRecentTasks.size();
9308            for (int i=0; i<N; i++) {
9309                TaskRecord tr = mRecentTasks.get(i);
9310                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
9311                        pw.println(tr);
9312                mRecentTasks.get(i).dump(pw, "    ");
9313            }
9314        }
9315
9316        pw.println(" ");
9317        pw.println("  mCurTask: " + mCurTask);
9318
9319        return true;
9320    }
9321
9322    boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9323            int opti, boolean dumpAll) {
9324        boolean needSep = false;
9325        int numPers = 0;
9326
9327        if (dumpAll) {
9328            for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
9329                final int NA = procs.size();
9330                for (int ia=0; ia<NA; ia++) {
9331                    if (!needSep) {
9332                        pw.println("  All known processes:");
9333                        needSep = true;
9334                    }
9335                    ProcessRecord r = procs.valueAt(ia);
9336                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
9337                        pw.print(" UID "); pw.print(procs.keyAt(ia));
9338                        pw.print(" "); pw.println(r);
9339                    r.dump(pw, "    ");
9340                    if (r.persistent) {
9341                        numPers++;
9342                    }
9343                }
9344            }
9345        }
9346
9347        if (mLruProcesses.size() > 0) {
9348            if (needSep) pw.println(" ");
9349            needSep = true;
9350            pw.println("  Running processes (most recent first):");
9351            dumpProcessList(pw, this, mLruProcesses, "    ",
9352                    "App ", "PERS", true);
9353            needSep = true;
9354        }
9355
9356        synchronized (mPidsSelfLocked) {
9357            if (mPidsSelfLocked.size() > 0) {
9358                if (needSep) pw.println(" ");
9359                needSep = true;
9360                pw.println("  PID mappings:");
9361                for (int i=0; i<mPidsSelfLocked.size(); i++) {
9362                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
9363                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
9364                }
9365            }
9366        }
9367
9368        if (mForegroundProcesses.size() > 0) {
9369            if (needSep) pw.println(" ");
9370            needSep = true;
9371            pw.println("  Foreground Processes:");
9372            for (int i=0; i<mForegroundProcesses.size(); i++) {
9373                pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
9374                        pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
9375            }
9376        }
9377
9378        if (mPersistentStartingProcesses.size() > 0) {
9379            if (needSep) pw.println(" ");
9380            needSep = true;
9381            pw.println("  Persisent processes that are starting:");
9382            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
9383                    "Starting Norm", "Restarting PERS", false);
9384        }
9385
9386        if (mStartingProcesses.size() > 0) {
9387            if (needSep) pw.println(" ");
9388            needSep = true;
9389            pw.println("  Processes that are starting:");
9390            dumpProcessList(pw, this, mStartingProcesses, "    ",
9391                    "Starting Norm", "Starting PERS", false);
9392        }
9393
9394        if (mRemovedProcesses.size() > 0) {
9395            if (needSep) pw.println(" ");
9396            needSep = true;
9397            pw.println("  Processes that are being removed:");
9398            dumpProcessList(pw, this, mRemovedProcesses, "    ",
9399                    "Removed Norm", "Removed PERS", false);
9400        }
9401
9402        if (mProcessesOnHold.size() > 0) {
9403            if (needSep) pw.println(" ");
9404            needSep = true;
9405            pw.println("  Processes that are on old until the system is ready:");
9406            dumpProcessList(pw, this, mProcessesOnHold, "    ",
9407                    "OnHold Norm", "OnHold PERS", false);
9408        }
9409
9410        if (mProcessesToGc.size() > 0) {
9411            if (needSep) pw.println(" ");
9412            needSep = true;
9413            pw.println("  Processes that are waiting to GC:");
9414            long now = SystemClock.uptimeMillis();
9415            for (int i=0; i<mProcessesToGc.size(); i++) {
9416                ProcessRecord proc = mProcessesToGc.get(i);
9417                pw.print("    Process "); pw.println(proc);
9418                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
9419                        pw.print(", last gced=");
9420                        pw.print(now-proc.lastRequestedGc);
9421                        pw.print(" ms ago, last lowMem=");
9422                        pw.print(now-proc.lastLowMemory);
9423                        pw.println(" ms ago");
9424
9425            }
9426        }
9427
9428        if (mProcessCrashTimes.getMap().size() > 0) {
9429            if (needSep) pw.println(" ");
9430            needSep = true;
9431            pw.println("  Time since processes crashed:");
9432            long now = SystemClock.uptimeMillis();
9433            for (Map.Entry<String, SparseArray<Long>> procs
9434                    : mProcessCrashTimes.getMap().entrySet()) {
9435                SparseArray<Long> uids = procs.getValue();
9436                final int N = uids.size();
9437                for (int i=0; i<N; i++) {
9438                    pw.print("    Process "); pw.print(procs.getKey());
9439                            pw.print(" uid "); pw.print(uids.keyAt(i));
9440                            pw.print(": last crashed ");
9441                            pw.print((now-uids.valueAt(i)));
9442                            pw.println(" ms ago");
9443                }
9444            }
9445        }
9446
9447        if (mBadProcesses.getMap().size() > 0) {
9448            if (needSep) pw.println(" ");
9449            needSep = true;
9450            pw.println("  Bad processes:");
9451            for (Map.Entry<String, SparseArray<Long>> procs
9452                    : mBadProcesses.getMap().entrySet()) {
9453                SparseArray<Long> uids = procs.getValue();
9454                final int N = uids.size();
9455                for (int i=0; i<N; i++) {
9456                    pw.print("    Bad process "); pw.print(procs.getKey());
9457                            pw.print(" uid "); pw.print(uids.keyAt(i));
9458                            pw.print(": crashed at time ");
9459                            pw.println(uids.valueAt(i));
9460                }
9461            }
9462        }
9463
9464        pw.println(" ");
9465        pw.println("  mHomeProcess: " + mHomeProcess);
9466        pw.println("  mConfiguration: " + mConfiguration);
9467        pw.println("  mSleeping=" + mSleeping + " mShuttingDown=" + mShuttingDown);
9468        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
9469                || mOrigWaitForDebugger) {
9470            pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
9471                    + " mDebugTransient=" + mDebugTransient
9472                    + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
9473        }
9474        if (mAlwaysFinishActivities || mController != null) {
9475            pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
9476                    + " mController=" + mController);
9477        }
9478        if (dumpAll) {
9479            pw.println("  Total persistent processes: " + numPers);
9480            pw.println("  mStartRunning=" + mStartRunning
9481                    + " mSystemReady=" + mSystemReady
9482                    + " mBooting=" + mBooting
9483                    + " mBooted=" + mBooted
9484                    + " mFactoryTest=" + mFactoryTest);
9485            pw.println("  mGoingToSleep=" + mGoingToSleep);
9486            pw.println("  mLaunchingActivity=" + mLaunchingActivity);
9487        }
9488
9489        return true;
9490    }
9491
9492    /**
9493     * There are three ways to call this:
9494     *  - no service specified: dump all the services
9495     *  - a flattened component name that matched an existing service was specified as the
9496     *    first arg: dump that one service
9497     *  - the first arg isn't the flattened component name of an existing service:
9498     *    dump all services whose component contains the first arg as a substring
9499     */
9500    protected void dumpService(FileDescriptor fd, PrintWriter pw, String[] args,
9501            int opti, boolean dumpAll) {
9502        String[] newArgs;
9503        String componentNameString;
9504        ServiceRecord r;
9505        if (opti <= args.length) {
9506            componentNameString = null;
9507            newArgs = EMPTY_STRING_ARRAY;
9508            r = null;
9509        } else {
9510            componentNameString = args[opti];
9511            opti++;
9512            ComponentName componentName = ComponentName.unflattenFromString(componentNameString);
9513            r = componentName != null ? mServices.get(componentName) : null;
9514            newArgs = new String[args.length - opti];
9515            if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
9516        }
9517
9518        if (r != null) {
9519            dumpService(fd, pw, r, newArgs);
9520        } else {
9521            for (ServiceRecord r1 : mServices.values()) {
9522                if (componentNameString == null
9523                        || r1.name.flattenToString().contains(componentNameString)) {
9524                    dumpService(fd, pw, r1, newArgs);
9525                }
9526            }
9527        }
9528    }
9529
9530    /**
9531     * Invokes IApplicationThread.dumpService() on the thread of the specified service if
9532     * there is a thread associated with the service.
9533     */
9534    private void dumpService(FileDescriptor fd, PrintWriter pw, ServiceRecord r, String[] args) {
9535        pw.println("  Service " + r.name.flattenToString());
9536        if (r.app != null && r.app.thread != null) {
9537            try {
9538                // flush anything that is already in the PrintWriter since the thread is going
9539                // to write to the file descriptor directly
9540                pw.flush();
9541                r.app.thread.dumpService(fd, r, args);
9542                pw.print("\n");
9543            } catch (RemoteException e) {
9544                pw.println("got a RemoteException while dumping the service");
9545            }
9546        }
9547    }
9548
9549    boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9550            int opti, boolean dumpAll) {
9551        boolean needSep = false;
9552
9553        if (dumpAll) {
9554            if (mRegisteredReceivers.size() > 0) {
9555                pw.println(" ");
9556                pw.println("  Registered Receivers:");
9557                Iterator it = mRegisteredReceivers.values().iterator();
9558                while (it.hasNext()) {
9559                    ReceiverList r = (ReceiverList)it.next();
9560                    pw.print("  * "); pw.println(r);
9561                    r.dump(pw, "    ");
9562                }
9563            }
9564
9565            pw.println(" ");
9566            pw.println("Receiver Resolver Table:");
9567            mReceiverResolver.dump(pw, "  ");
9568            needSep = true;
9569        }
9570
9571        if (mParallelBroadcasts.size() > 0 || mOrderedBroadcasts.size() > 0
9572                || mPendingBroadcast != null) {
9573            if (mParallelBroadcasts.size() > 0) {
9574                pw.println(" ");
9575                pw.println("  Active broadcasts:");
9576            }
9577            for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
9578                pw.println("  Broadcast #" + i + ":");
9579                mParallelBroadcasts.get(i).dump(pw, "    ");
9580            }
9581            if (mOrderedBroadcasts.size() > 0) {
9582                pw.println(" ");
9583                pw.println("  Active serialized broadcasts:");
9584            }
9585            for (int i=mOrderedBroadcasts.size()-1; i>=0; i--) {
9586                pw.println("  Serialized Broadcast #" + i + ":");
9587                mOrderedBroadcasts.get(i).dump(pw, "    ");
9588            }
9589            pw.println(" ");
9590            pw.println("  Pending broadcast:");
9591            if (mPendingBroadcast != null) {
9592                mPendingBroadcast.dump(pw, "    ");
9593            } else {
9594                pw.println("    (null)");
9595            }
9596            needSep = true;
9597        }
9598
9599        if (dumpAll) {
9600            pw.println(" ");
9601            pw.println("  Historical broadcasts:");
9602            for (int i=0; i<MAX_BROADCAST_HISTORY; i++) {
9603                BroadcastRecord r = mBroadcastHistory[i];
9604                if (r == null) {
9605                    break;
9606                }
9607                pw.println("  Historical Broadcast #" + i + ":");
9608                r.dump(pw, "    ");
9609            }
9610            needSep = true;
9611        }
9612
9613        if (mStickyBroadcasts != null) {
9614            pw.println(" ");
9615            pw.println("  Sticky broadcasts:");
9616            StringBuilder sb = new StringBuilder(128);
9617            for (Map.Entry<String, ArrayList<Intent>> ent
9618                    : mStickyBroadcasts.entrySet()) {
9619                pw.print("  * Sticky action "); pw.print(ent.getKey());
9620                        pw.println(":");
9621                ArrayList<Intent> intents = ent.getValue();
9622                final int N = intents.size();
9623                for (int i=0; i<N; i++) {
9624                    sb.setLength(0);
9625                    sb.append("    Intent: ");
9626                    intents.get(i).toShortString(sb, true, false);
9627                    pw.println(sb.toString());
9628                    Bundle bundle = intents.get(i).getExtras();
9629                    if (bundle != null) {
9630                        pw.print("      ");
9631                        pw.println(bundle.toString());
9632                    }
9633                }
9634            }
9635            needSep = true;
9636        }
9637
9638        if (dumpAll) {
9639            pw.println(" ");
9640            pw.println("  mBroadcastsScheduled=" + mBroadcastsScheduled);
9641            pw.println("  mHandler:");
9642            mHandler.dump(new PrintWriterPrinter(pw), "    ");
9643            needSep = true;
9644        }
9645
9646        return needSep;
9647    }
9648
9649    boolean dumpServicesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9650            int opti, boolean dumpAll) {
9651        boolean needSep = false;
9652
9653        if (dumpAll) {
9654            if (mServices.size() > 0) {
9655                pw.println("  Active services:");
9656                Iterator<ServiceRecord> it = mServices.values().iterator();
9657                while (it.hasNext()) {
9658                    ServiceRecord r = it.next();
9659                    pw.print("  * "); pw.println(r);
9660                    r.dump(pw, "    ");
9661                }
9662                needSep = true;
9663            }
9664        }
9665
9666        if (mPendingServices.size() > 0) {
9667            if (needSep) pw.println(" ");
9668            pw.println("  Pending services:");
9669            for (int i=0; i<mPendingServices.size(); i++) {
9670                ServiceRecord r = mPendingServices.get(i);
9671                pw.print("  * Pending "); pw.println(r);
9672                r.dump(pw, "    ");
9673            }
9674            needSep = true;
9675        }
9676
9677        if (mRestartingServices.size() > 0) {
9678            if (needSep) pw.println(" ");
9679            pw.println("  Restarting services:");
9680            for (int i=0; i<mRestartingServices.size(); i++) {
9681                ServiceRecord r = mRestartingServices.get(i);
9682                pw.print("  * Restarting "); pw.println(r);
9683                r.dump(pw, "    ");
9684            }
9685            needSep = true;
9686        }
9687
9688        if (mStoppingServices.size() > 0) {
9689            if (needSep) pw.println(" ");
9690            pw.println("  Stopping services:");
9691            for (int i=0; i<mStoppingServices.size(); i++) {
9692                ServiceRecord r = mStoppingServices.get(i);
9693                pw.print("  * Stopping "); pw.println(r);
9694                r.dump(pw, "    ");
9695            }
9696            needSep = true;
9697        }
9698
9699        if (dumpAll) {
9700            if (mServiceConnections.size() > 0) {
9701                if (needSep) pw.println(" ");
9702                pw.println("  Connection bindings to services:");
9703                Iterator<ConnectionRecord> it
9704                        = mServiceConnections.values().iterator();
9705                while (it.hasNext()) {
9706                    ConnectionRecord r = it.next();
9707                    pw.print("  * "); pw.println(r);
9708                    r.dump(pw, "    ");
9709                }
9710                needSep = true;
9711            }
9712        }
9713
9714        return needSep;
9715    }
9716
9717    boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9718            int opti, boolean dumpAll) {
9719        boolean needSep = false;
9720
9721        if (dumpAll) {
9722            if (mProvidersByClass.size() > 0) {
9723                if (needSep) pw.println(" ");
9724                pw.println("  Published content providers (by class):");
9725                Iterator it = mProvidersByClass.entrySet().iterator();
9726                while (it.hasNext()) {
9727                    Map.Entry e = (Map.Entry)it.next();
9728                    ContentProviderRecord r = (ContentProviderRecord)e.getValue();
9729                    pw.print("  * "); pw.println(r);
9730                    r.dump(pw, "    ");
9731                }
9732                needSep = true;
9733            }
9734
9735            if (mProvidersByName.size() > 0) {
9736                pw.println(" ");
9737                pw.println("  Authority to provider mappings:");
9738                Iterator it = mProvidersByName.entrySet().iterator();
9739                while (it.hasNext()) {
9740                    Map.Entry e = (Map.Entry)it.next();
9741                    ContentProviderRecord r = (ContentProviderRecord)e.getValue();
9742                    pw.print("  "); pw.print(e.getKey()); pw.print(": ");
9743                            pw.println(r);
9744                }
9745                needSep = true;
9746            }
9747        }
9748
9749        if (mLaunchingProviders.size() > 0) {
9750            if (needSep) pw.println(" ");
9751            pw.println("  Launching content providers:");
9752            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
9753                pw.print("  Launching #"); pw.print(i); pw.print(": ");
9754                        pw.println(mLaunchingProviders.get(i));
9755            }
9756            needSep = true;
9757        }
9758
9759        if (mGrantedUriPermissions.size() > 0) {
9760            pw.println();
9761            pw.println("Granted Uri Permissions:");
9762            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
9763                int uid = mGrantedUriPermissions.keyAt(i);
9764                HashMap<Uri, UriPermission> perms
9765                        = mGrantedUriPermissions.valueAt(i);
9766                pw.print("  * UID "); pw.print(uid);
9767                        pw.println(" holds:");
9768                for (UriPermission perm : perms.values()) {
9769                    pw.print("    "); pw.println(perm);
9770                    perm.dump(pw, "      ");
9771                }
9772            }
9773            needSep = true;
9774        }
9775
9776        return needSep;
9777    }
9778
9779    boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9780            int opti, boolean dumpAll) {
9781        boolean needSep = false;
9782
9783        if (dumpAll) {
9784            if (this.mIntentSenderRecords.size() > 0) {
9785                Iterator<WeakReference<PendingIntentRecord>> it
9786                        = mIntentSenderRecords.values().iterator();
9787                while (it.hasNext()) {
9788                    WeakReference<PendingIntentRecord> ref = it.next();
9789                    PendingIntentRecord rec = ref != null ? ref.get(): null;
9790                    needSep = true;
9791                    if (rec != null) {
9792                        pw.print("  * "); pw.println(rec);
9793                        rec.dump(pw, "    ");
9794                    } else {
9795                        pw.print("  * "); pw.print(ref);
9796                    }
9797                }
9798            }
9799        }
9800
9801        return needSep;
9802    }
9803
9804    private static final void dumpHistoryList(PrintWriter pw, List list,
9805            String prefix, String label, boolean complete) {
9806        TaskRecord lastTask = null;
9807        for (int i=list.size()-1; i>=0; i--) {
9808            HistoryRecord r = (HistoryRecord)list.get(i);
9809            final boolean full = complete || !r.inHistory;
9810            if (lastTask != r.task) {
9811                lastTask = r.task;
9812                pw.print(prefix);
9813                pw.print(full ? "* " : "  ");
9814                pw.println(lastTask);
9815                if (full) {
9816                    lastTask.dump(pw, prefix + "  ");
9817                }
9818            }
9819            pw.print(prefix); pw.print(full ? "  * " : "    "); pw.print(label);
9820            pw.print(" #"); pw.print(i); pw.print(": ");
9821            pw.println(r);
9822            if (full) {
9823                r.dump(pw, prefix + "      ");
9824            }
9825        }
9826    }
9827
9828    private static String buildOomTag(String prefix, String space, int val, int base) {
9829        if (val == base) {
9830            if (space == null) return prefix;
9831            return prefix + "  ";
9832        }
9833        return prefix + "+" + Integer.toString(val-base);
9834    }
9835
9836    private static final int dumpProcessList(PrintWriter pw,
9837            ActivityManagerService service, List list,
9838            String prefix, String normalLabel, String persistentLabel,
9839            boolean inclOomAdj) {
9840        int numPers = 0;
9841        for (int i=list.size()-1; i>=0; i--) {
9842            ProcessRecord r = (ProcessRecord)list.get(i);
9843            if (false) {
9844                pw.println(prefix + (r.persistent ? persistentLabel : normalLabel)
9845                      + " #" + i + ":");
9846                r.dump(pw, prefix + "  ");
9847            } else if (inclOomAdj) {
9848                String oomAdj;
9849                if (r.setAdj >= EMPTY_APP_ADJ) {
9850                    oomAdj = buildOomTag("empty", null, r.setAdj, EMPTY_APP_ADJ);
9851                } else if (r.setAdj >= HIDDEN_APP_MIN_ADJ) {
9852                    oomAdj = buildOomTag("bak", "  ", r.setAdj, HIDDEN_APP_MIN_ADJ);
9853                } else if (r.setAdj >= HOME_APP_ADJ) {
9854                    oomAdj = buildOomTag("home ", null, r.setAdj, HOME_APP_ADJ);
9855                } else if (r.setAdj >= SECONDARY_SERVER_ADJ) {
9856                    oomAdj = buildOomTag("svc", "  ", r.setAdj, SECONDARY_SERVER_ADJ);
9857                } else if (r.setAdj >= BACKUP_APP_ADJ) {
9858                    oomAdj = buildOomTag("bckup", null, r.setAdj, BACKUP_APP_ADJ);
9859                } else if (r.setAdj >= VISIBLE_APP_ADJ) {
9860                    oomAdj = buildOomTag("vis  ", null, r.setAdj, VISIBLE_APP_ADJ);
9861                } else if (r.setAdj >= FOREGROUND_APP_ADJ) {
9862                    oomAdj = buildOomTag("fore ", null, r.setAdj, FOREGROUND_APP_ADJ);
9863                } else if (r.setAdj >= CORE_SERVER_ADJ) {
9864                    oomAdj = buildOomTag("core ", null, r.setAdj, CORE_SERVER_ADJ);
9865                } else if (r.setAdj >= SYSTEM_ADJ) {
9866                    oomAdj = buildOomTag("sys  ", null, r.setAdj, SYSTEM_ADJ);
9867                } else {
9868                    oomAdj = Integer.toString(r.setAdj);
9869                }
9870                String schedGroup;
9871                switch (r.setSchedGroup) {
9872                    case Process.THREAD_GROUP_BG_NONINTERACTIVE:
9873                        schedGroup = "B";
9874                        break;
9875                    case Process.THREAD_GROUP_DEFAULT:
9876                        schedGroup = "F";
9877                        break;
9878                    default:
9879                        schedGroup = Integer.toString(r.setSchedGroup);
9880                        break;
9881                }
9882                pw.println(String.format("%s%s #%2d: adj=%s/%s %s (%s)",
9883                        prefix, (r.persistent ? persistentLabel : normalLabel),
9884                        i, oomAdj, schedGroup, r.toShortString(), r.adjType));
9885                if (r.adjSource != null || r.adjTarget != null) {
9886                    pw.println(prefix + "          " + r.adjTarget
9887                            + "<=" + r.adjSource);
9888                }
9889            } else {
9890                pw.println(String.format("%s%s #%2d: %s",
9891                        prefix, (r.persistent ? persistentLabel : normalLabel),
9892                        i, r.toString()));
9893            }
9894            if (r.persistent) {
9895                numPers++;
9896            }
9897        }
9898        return numPers;
9899    }
9900
9901    private static final void dumpApplicationMemoryUsage(FileDescriptor fd,
9902            PrintWriter pw, List list, String prefix, String[] args) {
9903        final boolean isCheckinRequest = scanArgs(args, "--checkin");
9904        long uptime = SystemClock.uptimeMillis();
9905        long realtime = SystemClock.elapsedRealtime();
9906
9907        if (isCheckinRequest) {
9908            // short checkin version
9909            pw.println(uptime + "," + realtime);
9910            pw.flush();
9911        } else {
9912            pw.println("Applications Memory Usage (kB):");
9913            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
9914        }
9915        for (int i = list.size() - 1 ; i >= 0 ; i--) {
9916            ProcessRecord r = (ProcessRecord)list.get(i);
9917            if (r.thread != null) {
9918                if (!isCheckinRequest) {
9919                    pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
9920                    pw.flush();
9921                }
9922                try {
9923                    r.thread.asBinder().dump(fd, args);
9924                } catch (RemoteException e) {
9925                    if (!isCheckinRequest) {
9926                        pw.println("Got RemoteException!");
9927                        pw.flush();
9928                    }
9929                }
9930            }
9931        }
9932    }
9933
9934    /**
9935     * Searches array of arguments for the specified string
9936     * @param args array of argument strings
9937     * @param value value to search for
9938     * @return true if the value is contained in the array
9939     */
9940    private static boolean scanArgs(String[] args, String value) {
9941        if (args != null) {
9942            for (String arg : args) {
9943                if (value.equals(arg)) {
9944                    return true;
9945                }
9946            }
9947        }
9948        return false;
9949    }
9950
9951    private final int indexOfTokenLocked(IBinder token) {
9952        int count = mHistory.size();
9953
9954        // convert the token to an entry in the history.
9955        HistoryRecord r = null;
9956        int index = -1;
9957        for (int i=count-1; i>=0; i--) {
9958            Object o = mHistory.get(i);
9959            if (o == token) {
9960                r = (HistoryRecord)o;
9961                index = i;
9962                break;
9963            }
9964        }
9965
9966        return index;
9967    }
9968
9969    private final void killServicesLocked(ProcessRecord app,
9970            boolean allowRestart) {
9971        // Report disconnected services.
9972        if (false) {
9973            // XXX we are letting the client link to the service for
9974            // death notifications.
9975            if (app.services.size() > 0) {
9976                Iterator it = app.services.iterator();
9977                while (it.hasNext()) {
9978                    ServiceRecord r = (ServiceRecord)it.next();
9979                    if (r.connections.size() > 0) {
9980                        Iterator<ConnectionRecord> jt
9981                                = r.connections.values().iterator();
9982                        while (jt.hasNext()) {
9983                            ConnectionRecord c = jt.next();
9984                            if (c.binding.client != app) {
9985                                try {
9986                                    //c.conn.connected(r.className, null);
9987                                } catch (Exception e) {
9988                                    // todo: this should be asynchronous!
9989                                    Log.w(TAG, "Exception thrown disconnected servce "
9990                                          + r.shortName
9991                                          + " from app " + app.processName, e);
9992                                }
9993                            }
9994                        }
9995                    }
9996                }
9997            }
9998        }
9999
10000        // Clean up any connections this application has to other services.
10001        if (app.connections.size() > 0) {
10002            Iterator<ConnectionRecord> it = app.connections.iterator();
10003            while (it.hasNext()) {
10004                ConnectionRecord r = it.next();
10005                removeConnectionLocked(r, app, null);
10006            }
10007        }
10008        app.connections.clear();
10009
10010        if (app.services.size() != 0) {
10011            // Any services running in the application need to be placed
10012            // back in the pending list.
10013            Iterator it = app.services.iterator();
10014            while (it.hasNext()) {
10015                ServiceRecord sr = (ServiceRecord)it.next();
10016                synchronized (sr.stats.getBatteryStats()) {
10017                    sr.stats.stopLaunchedLocked();
10018                }
10019                sr.app = null;
10020                sr.executeNesting = 0;
10021                mStoppingServices.remove(sr);
10022
10023                boolean hasClients = sr.bindings.size() > 0;
10024                if (hasClients) {
10025                    Iterator<IntentBindRecord> bindings
10026                            = sr.bindings.values().iterator();
10027                    while (bindings.hasNext()) {
10028                        IntentBindRecord b = bindings.next();
10029                        if (DEBUG_SERVICE) Log.v(TAG, "Killing binding " + b
10030                                + ": shouldUnbind=" + b.hasBound);
10031                        b.binder = null;
10032                        b.requested = b.received = b.hasBound = false;
10033                    }
10034                }
10035
10036                if (sr.crashCount >= 2) {
10037                    Log.w(TAG, "Service crashed " + sr.crashCount
10038                            + " times, stopping: " + sr);
10039                    EventLog.writeEvent(EventLogTags.AM_SERVICE_CRASHED_TOO_MUCH,
10040                            sr.crashCount, sr.shortName, app.pid);
10041                    bringDownServiceLocked(sr, true);
10042                } else if (!allowRestart) {
10043                    bringDownServiceLocked(sr, true);
10044                } else {
10045                    boolean canceled = scheduleServiceRestartLocked(sr, true);
10046
10047                    // Should the service remain running?  Note that in the
10048                    // extreme case of so many attempts to deliver a command
10049                    // that it failed, that we also will stop it here.
10050                    if (sr.startRequested && (sr.stopIfKilled || canceled)) {
10051                        if (sr.pendingStarts.size() == 0) {
10052                            sr.startRequested = false;
10053                            if (!hasClients) {
10054                                // Whoops, no reason to restart!
10055                                bringDownServiceLocked(sr, true);
10056                            }
10057                        }
10058                    }
10059                }
10060            }
10061
10062            if (!allowRestart) {
10063                app.services.clear();
10064            }
10065        }
10066
10067        // Make sure we have no more records on the stopping list.
10068        int i = mStoppingServices.size();
10069        while (i > 0) {
10070            i--;
10071            ServiceRecord sr = mStoppingServices.get(i);
10072            if (sr.app == app) {
10073                mStoppingServices.remove(i);
10074            }
10075        }
10076
10077        app.executingServices.clear();
10078    }
10079
10080    private final void removeDyingProviderLocked(ProcessRecord proc,
10081            ContentProviderRecord cpr) {
10082        synchronized (cpr) {
10083            cpr.launchingApp = null;
10084            cpr.notifyAll();
10085        }
10086
10087        mProvidersByClass.remove(cpr.info.name);
10088        String names[] = cpr.info.authority.split(";");
10089        for (int j = 0; j < names.length; j++) {
10090            mProvidersByName.remove(names[j]);
10091        }
10092
10093        Iterator<ProcessRecord> cit = cpr.clients.iterator();
10094        while (cit.hasNext()) {
10095            ProcessRecord capp = cit.next();
10096            if (!capp.persistent && capp.thread != null
10097                    && capp.pid != 0
10098                    && capp.pid != MY_PID) {
10099                Log.i(TAG, "Killing app " + capp.processName
10100                        + " (pid " + capp.pid
10101                        + ") because provider " + cpr.info.name
10102                        + " is in dying process " + proc.processName);
10103                Process.killProcess(capp.pid);
10104            }
10105        }
10106
10107        mLaunchingProviders.remove(cpr);
10108    }
10109
10110    /**
10111     * Main code for cleaning up a process when it has gone away.  This is
10112     * called both as a result of the process dying, or directly when stopping
10113     * a process when running in single process mode.
10114     */
10115    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
10116            boolean restarting, int index) {
10117        if (index >= 0) {
10118            mLruProcesses.remove(index);
10119        }
10120
10121        mProcessesToGc.remove(app);
10122
10123        // Dismiss any open dialogs.
10124        if (app.crashDialog != null) {
10125            app.crashDialog.dismiss();
10126            app.crashDialog = null;
10127        }
10128        if (app.anrDialog != null) {
10129            app.anrDialog.dismiss();
10130            app.anrDialog = null;
10131        }
10132        if (app.waitDialog != null) {
10133            app.waitDialog.dismiss();
10134            app.waitDialog = null;
10135        }
10136
10137        app.crashing = false;
10138        app.notResponding = false;
10139
10140        app.resetPackageList();
10141        app.thread = null;
10142        app.forcingToForeground = null;
10143        app.foregroundServices = false;
10144
10145        killServicesLocked(app, true);
10146
10147        boolean restart = false;
10148
10149        int NL = mLaunchingProviders.size();
10150
10151        // Remove published content providers.
10152        if (!app.pubProviders.isEmpty()) {
10153            Iterator it = app.pubProviders.values().iterator();
10154            while (it.hasNext()) {
10155                ContentProviderRecord cpr = (ContentProviderRecord)it.next();
10156                cpr.provider = null;
10157                cpr.app = null;
10158
10159                // See if someone is waiting for this provider...  in which
10160                // case we don't remove it, but just let it restart.
10161                int i = 0;
10162                if (!app.bad) {
10163                    for (; i<NL; i++) {
10164                        if (mLaunchingProviders.get(i) == cpr) {
10165                            restart = true;
10166                            break;
10167                        }
10168                    }
10169                } else {
10170                    i = NL;
10171                }
10172
10173                if (i >= NL) {
10174                    removeDyingProviderLocked(app, cpr);
10175                    NL = mLaunchingProviders.size();
10176                }
10177            }
10178            app.pubProviders.clear();
10179        }
10180
10181        // Take care of any launching providers waiting for this process.
10182        if (checkAppInLaunchingProvidersLocked(app, false)) {
10183            restart = true;
10184        }
10185
10186        // Unregister from connected content providers.
10187        if (!app.conProviders.isEmpty()) {
10188            Iterator it = app.conProviders.keySet().iterator();
10189            while (it.hasNext()) {
10190                ContentProviderRecord cpr = (ContentProviderRecord)it.next();
10191                cpr.clients.remove(app);
10192            }
10193            app.conProviders.clear();
10194        }
10195
10196        // At this point there may be remaining entries in mLaunchingProviders
10197        // where we were the only one waiting, so they are no longer of use.
10198        // Look for these and clean up if found.
10199        // XXX Commented out for now.  Trying to figure out a way to reproduce
10200        // the actual situation to identify what is actually going on.
10201        if (false) {
10202            for (int i=0; i<NL; i++) {
10203                ContentProviderRecord cpr = (ContentProviderRecord)
10204                        mLaunchingProviders.get(i);
10205                if (cpr.clients.size() <= 0 && cpr.externals <= 0) {
10206                    synchronized (cpr) {
10207                        cpr.launchingApp = null;
10208                        cpr.notifyAll();
10209                    }
10210                }
10211            }
10212        }
10213
10214        skipCurrentReceiverLocked(app);
10215
10216        // Unregister any receivers.
10217        if (app.receivers.size() > 0) {
10218            Iterator<ReceiverList> it = app.receivers.iterator();
10219            while (it.hasNext()) {
10220                removeReceiverLocked(it.next());
10221            }
10222            app.receivers.clear();
10223        }
10224
10225        // If the app is undergoing backup, tell the backup manager about it
10226        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
10227            if (DEBUG_BACKUP) Log.d(TAG, "App " + mBackupTarget.appInfo + " died during backup");
10228            try {
10229                IBackupManager bm = IBackupManager.Stub.asInterface(
10230                        ServiceManager.getService(Context.BACKUP_SERVICE));
10231                bm.agentDisconnected(app.info.packageName);
10232            } catch (RemoteException e) {
10233                // can't happen; backup manager is local
10234            }
10235        }
10236
10237        // If the caller is restarting this app, then leave it in its
10238        // current lists and let the caller take care of it.
10239        if (restarting) {
10240            return;
10241        }
10242
10243        if (!app.persistent) {
10244            if (DEBUG_PROCESSES) Log.v(TAG,
10245                    "Removing non-persistent process during cleanup: " + app);
10246            mProcessNames.remove(app.processName, app.info.uid);
10247        } else if (!app.removed) {
10248            // This app is persistent, so we need to keep its record around.
10249            // If it is not already on the pending app list, add it there
10250            // and start a new process for it.
10251            app.thread = null;
10252            app.forcingToForeground = null;
10253            app.foregroundServices = false;
10254            if (mPersistentStartingProcesses.indexOf(app) < 0) {
10255                mPersistentStartingProcesses.add(app);
10256                restart = true;
10257            }
10258        }
10259        mProcessesOnHold.remove(app);
10260
10261        if (app == mHomeProcess) {
10262            mHomeProcess = null;
10263        }
10264
10265        if (restart) {
10266            // We have components that still need to be running in the
10267            // process, so re-launch it.
10268            mProcessNames.put(app.processName, app.info.uid, app);
10269            startProcessLocked(app, "restart", app.processName);
10270        } else if (app.pid > 0 && app.pid != MY_PID) {
10271            // Goodbye!
10272            synchronized (mPidsSelfLocked) {
10273                mPidsSelfLocked.remove(app.pid);
10274                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
10275            }
10276            app.setPid(0);
10277        }
10278    }
10279
10280    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
10281        // Look through the content providers we are waiting to have launched,
10282        // and if any run in this process then either schedule a restart of
10283        // the process or kill the client waiting for it if this process has
10284        // gone bad.
10285        int NL = mLaunchingProviders.size();
10286        boolean restart = false;
10287        for (int i=0; i<NL; i++) {
10288            ContentProviderRecord cpr = (ContentProviderRecord)
10289                    mLaunchingProviders.get(i);
10290            if (cpr.launchingApp == app) {
10291                if (!alwaysBad && !app.bad) {
10292                    restart = true;
10293                } else {
10294                    removeDyingProviderLocked(app, cpr);
10295                    NL = mLaunchingProviders.size();
10296                }
10297            }
10298        }
10299        return restart;
10300    }
10301
10302    // =========================================================
10303    // SERVICES
10304    // =========================================================
10305
10306    ActivityManager.RunningServiceInfo makeRunningServiceInfoLocked(ServiceRecord r) {
10307        ActivityManager.RunningServiceInfo info =
10308            new ActivityManager.RunningServiceInfo();
10309        info.service = r.name;
10310        if (r.app != null) {
10311            info.pid = r.app.pid;
10312        }
10313        info.uid = r.appInfo.uid;
10314        info.process = r.processName;
10315        info.foreground = r.isForeground;
10316        info.activeSince = r.createTime;
10317        info.started = r.startRequested;
10318        info.clientCount = r.connections.size();
10319        info.crashCount = r.crashCount;
10320        info.lastActivityTime = r.lastActivity;
10321        if (r.isForeground) {
10322            info.flags |= ActivityManager.RunningServiceInfo.FLAG_FOREGROUND;
10323        }
10324        if (r.startRequested) {
10325            info.flags |= ActivityManager.RunningServiceInfo.FLAG_STARTED;
10326        }
10327        if (r.app != null && r.app.pid == MY_PID) {
10328            info.flags |= ActivityManager.RunningServiceInfo.FLAG_SYSTEM_PROCESS;
10329        }
10330        if (r.app != null && r.app.persistent) {
10331            info.flags |= ActivityManager.RunningServiceInfo.FLAG_PERSISTENT_PROCESS;
10332        }
10333        for (ConnectionRecord conn : r.connections.values()) {
10334            if (conn.clientLabel != 0) {
10335                info.clientPackage = conn.binding.client.info.packageName;
10336                info.clientLabel = conn.clientLabel;
10337                break;
10338            }
10339        }
10340        return info;
10341    }
10342
10343    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
10344            int flags) {
10345        synchronized (this) {
10346            ArrayList<ActivityManager.RunningServiceInfo> res
10347                    = new ArrayList<ActivityManager.RunningServiceInfo>();
10348
10349            if (mServices.size() > 0) {
10350                Iterator<ServiceRecord> it = mServices.values().iterator();
10351                while (it.hasNext() && res.size() < maxNum) {
10352                    res.add(makeRunningServiceInfoLocked(it.next()));
10353                }
10354            }
10355
10356            for (int i=0; i<mRestartingServices.size() && res.size() < maxNum; i++) {
10357                ServiceRecord r = mRestartingServices.get(i);
10358                ActivityManager.RunningServiceInfo info =
10359                        makeRunningServiceInfoLocked(r);
10360                info.restarting = r.nextRestartTime;
10361                res.add(info);
10362            }
10363
10364            return res;
10365        }
10366    }
10367
10368    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
10369        synchronized (this) {
10370            ServiceRecord r = mServices.get(name);
10371            if (r != null) {
10372                for (ConnectionRecord conn : r.connections.values()) {
10373                    if (conn.clientIntent != null) {
10374                        return conn.clientIntent;
10375                    }
10376                }
10377            }
10378        }
10379        return null;
10380    }
10381
10382    private final ServiceRecord findServiceLocked(ComponentName name,
10383            IBinder token) {
10384        ServiceRecord r = mServices.get(name);
10385        return r == token ? r : null;
10386    }
10387
10388    private final class ServiceLookupResult {
10389        final ServiceRecord record;
10390        final String permission;
10391
10392        ServiceLookupResult(ServiceRecord _record, String _permission) {
10393            record = _record;
10394            permission = _permission;
10395        }
10396    };
10397
10398    private ServiceLookupResult findServiceLocked(Intent service,
10399            String resolvedType) {
10400        ServiceRecord r = null;
10401        if (service.getComponent() != null) {
10402            r = mServices.get(service.getComponent());
10403        }
10404        if (r == null) {
10405            Intent.FilterComparison filter = new Intent.FilterComparison(service);
10406            r = mServicesByIntent.get(filter);
10407        }
10408
10409        if (r == null) {
10410            try {
10411                ResolveInfo rInfo =
10412                    ActivityThread.getPackageManager().resolveService(
10413                            service, resolvedType, 0);
10414                ServiceInfo sInfo =
10415                    rInfo != null ? rInfo.serviceInfo : null;
10416                if (sInfo == null) {
10417                    return null;
10418                }
10419
10420                ComponentName name = new ComponentName(
10421                        sInfo.applicationInfo.packageName, sInfo.name);
10422                r = mServices.get(name);
10423            } catch (RemoteException ex) {
10424                // pm is in same process, this will never happen.
10425            }
10426        }
10427        if (r != null) {
10428            int callingPid = Binder.getCallingPid();
10429            int callingUid = Binder.getCallingUid();
10430            if (checkComponentPermission(r.permission,
10431                    callingPid, callingUid, r.exported ? -1 : r.appInfo.uid)
10432                    != PackageManager.PERMISSION_GRANTED) {
10433                Log.w(TAG, "Permission Denial: Accessing service " + r.name
10434                        + " from pid=" + callingPid
10435                        + ", uid=" + callingUid
10436                        + " requires " + r.permission);
10437                return new ServiceLookupResult(null, r.permission);
10438            }
10439            return new ServiceLookupResult(r, null);
10440        }
10441        return null;
10442    }
10443
10444    private class ServiceRestarter implements Runnable {
10445        private ServiceRecord mService;
10446
10447        void setService(ServiceRecord service) {
10448            mService = service;
10449        }
10450
10451        public void run() {
10452            synchronized(ActivityManagerService.this) {
10453                performServiceRestartLocked(mService);
10454            }
10455        }
10456    }
10457
10458    private ServiceLookupResult retrieveServiceLocked(Intent service,
10459            String resolvedType, int callingPid, int callingUid) {
10460        ServiceRecord r = null;
10461        if (service.getComponent() != null) {
10462            r = mServices.get(service.getComponent());
10463        }
10464        Intent.FilterComparison filter = new Intent.FilterComparison(service);
10465        r = mServicesByIntent.get(filter);
10466        if (r == null) {
10467            try {
10468                ResolveInfo rInfo =
10469                    ActivityThread.getPackageManager().resolveService(
10470                            service, resolvedType, STOCK_PM_FLAGS);
10471                ServiceInfo sInfo =
10472                    rInfo != null ? rInfo.serviceInfo : null;
10473                if (sInfo == null) {
10474                    Log.w(TAG, "Unable to start service " + service +
10475                          ": not found");
10476                    return null;
10477                }
10478
10479                ComponentName name = new ComponentName(
10480                        sInfo.applicationInfo.packageName, sInfo.name);
10481                r = mServices.get(name);
10482                if (r == null) {
10483                    filter = new Intent.FilterComparison(service.cloneFilter());
10484                    ServiceRestarter res = new ServiceRestarter();
10485                    BatteryStatsImpl.Uid.Pkg.Serv ss = null;
10486                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10487                    synchronized (stats) {
10488                        ss = stats.getServiceStatsLocked(
10489                                sInfo.applicationInfo.uid, sInfo.packageName,
10490                                sInfo.name);
10491                    }
10492                    r = new ServiceRecord(this, ss, name, filter, sInfo, res);
10493                    res.setService(r);
10494                    mServices.put(name, r);
10495                    mServicesByIntent.put(filter, r);
10496
10497                    // Make sure this component isn't in the pending list.
10498                    int N = mPendingServices.size();
10499                    for (int i=0; i<N; i++) {
10500                        ServiceRecord pr = mPendingServices.get(i);
10501                        if (pr.name.equals(name)) {
10502                            mPendingServices.remove(i);
10503                            i--;
10504                            N--;
10505                        }
10506                    }
10507                }
10508            } catch (RemoteException ex) {
10509                // pm is in same process, this will never happen.
10510            }
10511        }
10512        if (r != null) {
10513            if (checkComponentPermission(r.permission,
10514                    callingPid, callingUid, r.exported ? -1 : r.appInfo.uid)
10515                    != PackageManager.PERMISSION_GRANTED) {
10516                Log.w(TAG, "Permission Denial: Accessing service " + r.name
10517                        + " from pid=" + Binder.getCallingPid()
10518                        + ", uid=" + Binder.getCallingUid()
10519                        + " requires " + r.permission);
10520                return new ServiceLookupResult(null, r.permission);
10521            }
10522            return new ServiceLookupResult(r, null);
10523        }
10524        return null;
10525    }
10526
10527    private final void bumpServiceExecutingLocked(ServiceRecord r) {
10528        long now = SystemClock.uptimeMillis();
10529        if (r.executeNesting == 0 && r.app != null) {
10530            if (r.app.executingServices.size() == 0) {
10531                Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
10532                msg.obj = r.app;
10533                mHandler.sendMessageAtTime(msg, now+SERVICE_TIMEOUT);
10534            }
10535            r.app.executingServices.add(r);
10536        }
10537        r.executeNesting++;
10538        r.executingStart = now;
10539    }
10540
10541    private final void sendServiceArgsLocked(ServiceRecord r,
10542            boolean oomAdjusted) {
10543        final int N = r.pendingStarts.size();
10544        if (N == 0) {
10545            return;
10546        }
10547
10548        int i = 0;
10549        while (i < N) {
10550            try {
10551                ServiceRecord.StartItem si = r.pendingStarts.get(i);
10552                if (DEBUG_SERVICE) Log.v(TAG, "Sending arguments to service: "
10553                        + r.name + " " + r.intent + " args=" + si.intent);
10554                if (si.intent == null && N > 1) {
10555                    // If somehow we got a dummy start at the front, then
10556                    // just drop it here.
10557                    i++;
10558                    continue;
10559                }
10560                bumpServiceExecutingLocked(r);
10561                if (!oomAdjusted) {
10562                    oomAdjusted = true;
10563                    updateOomAdjLocked(r.app);
10564                }
10565                int flags = 0;
10566                if (si.deliveryCount > 0) {
10567                    flags |= Service.START_FLAG_RETRY;
10568                }
10569                if (si.doneExecutingCount > 0) {
10570                    flags |= Service.START_FLAG_REDELIVERY;
10571                }
10572                r.app.thread.scheduleServiceArgs(r, si.id, flags, si.intent);
10573                si.deliveredTime = SystemClock.uptimeMillis();
10574                r.deliveredStarts.add(si);
10575                si.deliveryCount++;
10576                i++;
10577            } catch (RemoteException e) {
10578                // Remote process gone...  we'll let the normal cleanup take
10579                // care of this.
10580                break;
10581            } catch (Exception e) {
10582                Log.w(TAG, "Unexpected exception", e);
10583                break;
10584            }
10585        }
10586        if (i == N) {
10587            r.pendingStarts.clear();
10588        } else {
10589            while (i > 0) {
10590                i--;
10591                r.pendingStarts.remove(i);
10592            }
10593        }
10594    }
10595
10596    private final boolean requestServiceBindingLocked(ServiceRecord r,
10597            IntentBindRecord i, boolean rebind) {
10598        if (r.app == null || r.app.thread == null) {
10599            // If service is not currently running, can't yet bind.
10600            return false;
10601        }
10602        if ((!i.requested || rebind) && i.apps.size() > 0) {
10603            try {
10604                bumpServiceExecutingLocked(r);
10605                if (DEBUG_SERVICE) Log.v(TAG, "Connecting binding " + i
10606                        + ": shouldUnbind=" + i.hasBound);
10607                r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind);
10608                if (!rebind) {
10609                    i.requested = true;
10610                }
10611                i.hasBound = true;
10612                i.doRebind = false;
10613            } catch (RemoteException e) {
10614                return false;
10615            }
10616        }
10617        return true;
10618    }
10619
10620    private final void requestServiceBindingsLocked(ServiceRecord r) {
10621        Iterator<IntentBindRecord> bindings = r.bindings.values().iterator();
10622        while (bindings.hasNext()) {
10623            IntentBindRecord i = bindings.next();
10624            if (!requestServiceBindingLocked(r, i, false)) {
10625                break;
10626            }
10627        }
10628    }
10629
10630    private final void realStartServiceLocked(ServiceRecord r,
10631            ProcessRecord app) throws RemoteException {
10632        if (app.thread == null) {
10633            throw new RemoteException();
10634        }
10635
10636        r.app = app;
10637        r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
10638
10639        app.services.add(r);
10640        bumpServiceExecutingLocked(r);
10641        updateLruProcessLocked(app, true, true);
10642
10643        boolean created = false;
10644        try {
10645            if (DEBUG_SERVICE) Log.v(TAG, "Scheduling start service: "
10646                    + r.name + " " + r.intent);
10647            mStringBuilder.setLength(0);
10648            r.intent.getIntent().toShortString(mStringBuilder, false, true);
10649            EventLog.writeEvent(EventLogTags.AM_CREATE_SERVICE,
10650                    System.identityHashCode(r), r.shortName,
10651                    mStringBuilder.toString(), r.app.pid);
10652            synchronized (r.stats.getBatteryStats()) {
10653                r.stats.startLaunchedLocked();
10654            }
10655            ensurePackageDexOpt(r.serviceInfo.packageName);
10656            app.thread.scheduleCreateService(r, r.serviceInfo);
10657            r.postNotification();
10658            created = true;
10659        } finally {
10660            if (!created) {
10661                app.services.remove(r);
10662                scheduleServiceRestartLocked(r, false);
10663            }
10664        }
10665
10666        requestServiceBindingsLocked(r);
10667
10668        // If the service is in the started state, and there are no
10669        // pending arguments, then fake up one so its onStartCommand() will
10670        // be called.
10671        if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
10672            r.lastStartId++;
10673            if (r.lastStartId < 1) {
10674                r.lastStartId = 1;
10675            }
10676            r.pendingStarts.add(new ServiceRecord.StartItem(r.lastStartId, null));
10677        }
10678
10679        sendServiceArgsLocked(r, true);
10680    }
10681
10682    private final boolean scheduleServiceRestartLocked(ServiceRecord r,
10683            boolean allowCancel) {
10684        boolean canceled = false;
10685
10686        final long now = SystemClock.uptimeMillis();
10687        long minDuration = SERVICE_RESTART_DURATION;
10688        long resetTime = SERVICE_RESET_RUN_DURATION;
10689
10690        // Any delivered but not yet finished starts should be put back
10691        // on the pending list.
10692        final int N = r.deliveredStarts.size();
10693        if (N > 0) {
10694            for (int i=N-1; i>=0; i--) {
10695                ServiceRecord.StartItem si = r.deliveredStarts.get(i);
10696                if (si.intent == null) {
10697                    // We'll generate this again if needed.
10698                } else if (!allowCancel || (si.deliveryCount < ServiceRecord.MAX_DELIVERY_COUNT
10699                        && si.doneExecutingCount < ServiceRecord.MAX_DONE_EXECUTING_COUNT)) {
10700                    r.pendingStarts.add(0, si);
10701                    long dur = SystemClock.uptimeMillis() - si.deliveredTime;
10702                    dur *= 2;
10703                    if (minDuration < dur) minDuration = dur;
10704                    if (resetTime < dur) resetTime = dur;
10705                } else {
10706                    Log.w(TAG, "Canceling start item " + si.intent + " in service "
10707                            + r.name);
10708                    canceled = true;
10709                }
10710            }
10711            r.deliveredStarts.clear();
10712        }
10713
10714        r.totalRestartCount++;
10715        if (r.restartDelay == 0) {
10716            r.restartCount++;
10717            r.restartDelay = minDuration;
10718        } else {
10719            // If it has been a "reasonably long time" since the service
10720            // was started, then reset our restart duration back to
10721            // the beginning, so we don't infinitely increase the duration
10722            // on a service that just occasionally gets killed (which is
10723            // a normal case, due to process being killed to reclaim memory).
10724            if (now > (r.restartTime+resetTime)) {
10725                r.restartCount = 1;
10726                r.restartDelay = minDuration;
10727            } else {
10728                r.restartDelay *= SERVICE_RESTART_DURATION_FACTOR;
10729                if (r.restartDelay < minDuration) {
10730                    r.restartDelay = minDuration;
10731                }
10732            }
10733        }
10734
10735        r.nextRestartTime = now + r.restartDelay;
10736
10737        // Make sure that we don't end up restarting a bunch of services
10738        // all at the same time.
10739        boolean repeat;
10740        do {
10741            repeat = false;
10742            for (int i=mRestartingServices.size()-1; i>=0; i--) {
10743                ServiceRecord r2 = mRestartingServices.get(i);
10744                if (r2 != r && r.nextRestartTime
10745                        >= (r2.nextRestartTime-SERVICE_MIN_RESTART_TIME_BETWEEN)
10746                        && r.nextRestartTime
10747                        < (r2.nextRestartTime+SERVICE_MIN_RESTART_TIME_BETWEEN)) {
10748                    r.nextRestartTime = r2.nextRestartTime + SERVICE_MIN_RESTART_TIME_BETWEEN;
10749                    r.restartDelay = r.nextRestartTime - now;
10750                    repeat = true;
10751                    break;
10752                }
10753            }
10754        } while (repeat);
10755
10756        if (!mRestartingServices.contains(r)) {
10757            mRestartingServices.add(r);
10758        }
10759
10760        r.cancelNotification();
10761
10762        mHandler.removeCallbacks(r.restarter);
10763        mHandler.postAtTime(r.restarter, r.nextRestartTime);
10764        r.nextRestartTime = SystemClock.uptimeMillis() + r.restartDelay;
10765        Log.w(TAG, "Scheduling restart of crashed service "
10766                + r.shortName + " in " + r.restartDelay + "ms");
10767        EventLog.writeEvent(EventLogTags.AM_SCHEDULE_SERVICE_RESTART,
10768                r.shortName, r.restartDelay);
10769
10770        Message msg = Message.obtain();
10771        msg.what = SERVICE_ERROR_MSG;
10772        msg.obj = r;
10773        mHandler.sendMessage(msg);
10774
10775        return canceled;
10776    }
10777
10778    final void performServiceRestartLocked(ServiceRecord r) {
10779        if (!mRestartingServices.contains(r)) {
10780            return;
10781        }
10782        bringUpServiceLocked(r, r.intent.getIntent().getFlags(), true);
10783    }
10784
10785    private final boolean unscheduleServiceRestartLocked(ServiceRecord r) {
10786        if (r.restartDelay == 0) {
10787            return false;
10788        }
10789        r.resetRestartCounter();
10790        mRestartingServices.remove(r);
10791        mHandler.removeCallbacks(r.restarter);
10792        return true;
10793    }
10794
10795    private final boolean bringUpServiceLocked(ServiceRecord r,
10796            int intentFlags, boolean whileRestarting) {
10797        //Log.i(TAG, "Bring up service:");
10798        //r.dump("  ");
10799
10800        if (r.app != null && r.app.thread != null) {
10801            sendServiceArgsLocked(r, false);
10802            return true;
10803        }
10804
10805        if (!whileRestarting && r.restartDelay > 0) {
10806            // If waiting for a restart, then do nothing.
10807            return true;
10808        }
10809
10810        if (DEBUG_SERVICE) Log.v(TAG, "Bringing up service " + r.name
10811                + " " + r.intent);
10812
10813        // We are now bringing the service up, so no longer in the
10814        // restarting state.
10815        mRestartingServices.remove(r);
10816
10817        final String appName = r.processName;
10818        ProcessRecord app = getProcessRecordLocked(appName, r.appInfo.uid);
10819        if (app != null && app.thread != null) {
10820            try {
10821                realStartServiceLocked(r, app);
10822                return true;
10823            } catch (RemoteException e) {
10824                Log.w(TAG, "Exception when starting service " + r.shortName, e);
10825            }
10826
10827            // If a dead object exception was thrown -- fall through to
10828            // restart the application.
10829        }
10830
10831        // Not running -- get it started, and enqueue this service record
10832        // to be executed when the app comes up.
10833        if (startProcessLocked(appName, r.appInfo, true, intentFlags,
10834                "service", r.name, false) == null) {
10835            Log.w(TAG, "Unable to launch app "
10836                    + r.appInfo.packageName + "/"
10837                    + r.appInfo.uid + " for service "
10838                    + r.intent.getIntent() + ": process is bad");
10839            bringDownServiceLocked(r, true);
10840            return false;
10841        }
10842
10843        if (!mPendingServices.contains(r)) {
10844            mPendingServices.add(r);
10845        }
10846
10847        return true;
10848    }
10849
10850    private final void bringDownServiceLocked(ServiceRecord r, boolean force) {
10851        //Log.i(TAG, "Bring down service:");
10852        //r.dump("  ");
10853
10854        // Does it still need to run?
10855        if (!force && r.startRequested) {
10856            return;
10857        }
10858        if (r.connections.size() > 0) {
10859            if (!force) {
10860                // XXX should probably keep a count of the number of auto-create
10861                // connections directly in the service.
10862                Iterator<ConnectionRecord> it = r.connections.values().iterator();
10863                while (it.hasNext()) {
10864                    ConnectionRecord cr = it.next();
10865                    if ((cr.flags&Context.BIND_AUTO_CREATE) != 0) {
10866                        return;
10867                    }
10868                }
10869            }
10870
10871            // Report to all of the connections that the service is no longer
10872            // available.
10873            Iterator<ConnectionRecord> it = r.connections.values().iterator();
10874            while (it.hasNext()) {
10875                ConnectionRecord c = it.next();
10876                try {
10877                    // todo: shouldn't be a synchronous call!
10878                    c.conn.connected(r.name, null);
10879                } catch (Exception e) {
10880                    Log.w(TAG, "Failure disconnecting service " + r.name +
10881                          " to connection " + c.conn.asBinder() +
10882                          " (in " + c.binding.client.processName + ")", e);
10883                }
10884            }
10885        }
10886
10887        // Tell the service that it has been unbound.
10888        if (r.bindings.size() > 0 && r.app != null && r.app.thread != null) {
10889            Iterator<IntentBindRecord> it = r.bindings.values().iterator();
10890            while (it.hasNext()) {
10891                IntentBindRecord ibr = it.next();
10892                if (DEBUG_SERVICE) Log.v(TAG, "Bringing down binding " + ibr
10893                        + ": hasBound=" + ibr.hasBound);
10894                if (r.app != null && r.app.thread != null && ibr.hasBound) {
10895                    try {
10896                        bumpServiceExecutingLocked(r);
10897                        updateOomAdjLocked(r.app);
10898                        ibr.hasBound = false;
10899                        r.app.thread.scheduleUnbindService(r,
10900                                ibr.intent.getIntent());
10901                    } catch (Exception e) {
10902                        Log.w(TAG, "Exception when unbinding service "
10903                                + r.shortName, e);
10904                        serviceDoneExecutingLocked(r, true);
10905                    }
10906                }
10907            }
10908        }
10909
10910        if (DEBUG_SERVICE) Log.v(TAG, "Bringing down service " + r.name
10911                 + " " + r.intent);
10912        EventLog.writeEvent(EventLogTags.AM_DESTROY_SERVICE,
10913                System.identityHashCode(r), r.shortName,
10914                (r.app != null) ? r.app.pid : -1);
10915
10916        mServices.remove(r.name);
10917        mServicesByIntent.remove(r.intent);
10918        if (localLOGV) Log.v(TAG, "BRING DOWN SERVICE: " + r.shortName);
10919        r.totalRestartCount = 0;
10920        unscheduleServiceRestartLocked(r);
10921
10922        // Also make sure it is not on the pending list.
10923        int N = mPendingServices.size();
10924        for (int i=0; i<N; i++) {
10925            if (mPendingServices.get(i) == r) {
10926                mPendingServices.remove(i);
10927                if (DEBUG_SERVICE) Log.v(
10928                    TAG, "Removed pending service: " + r.shortName);
10929                i--;
10930                N--;
10931            }
10932        }
10933
10934        r.cancelNotification();
10935        r.isForeground = false;
10936        r.foregroundId = 0;
10937        r.foregroundNoti = null;
10938
10939        // Clear start entries.
10940        r.deliveredStarts.clear();
10941        r.pendingStarts.clear();
10942
10943        if (r.app != null) {
10944            synchronized (r.stats.getBatteryStats()) {
10945                r.stats.stopLaunchedLocked();
10946            }
10947            r.app.services.remove(r);
10948            if (r.app.thread != null) {
10949                try {
10950                    if (DEBUG_SERVICE) Log.v(TAG,
10951                            "Stopping service: " + r.shortName);
10952                    bumpServiceExecutingLocked(r);
10953                    mStoppingServices.add(r);
10954                    updateOomAdjLocked(r.app);
10955                    r.app.thread.scheduleStopService(r);
10956                } catch (Exception e) {
10957                    Log.w(TAG, "Exception when stopping service "
10958                            + r.shortName, e);
10959                    serviceDoneExecutingLocked(r, true);
10960                }
10961                updateServiceForegroundLocked(r.app, false);
10962            } else {
10963                if (DEBUG_SERVICE) Log.v(
10964                    TAG, "Removed service that has no process: " + r.shortName);
10965            }
10966        } else {
10967            if (DEBUG_SERVICE) Log.v(
10968                TAG, "Removed service that is not running: " + r.shortName);
10969        }
10970    }
10971
10972    ComponentName startServiceLocked(IApplicationThread caller,
10973            Intent service, String resolvedType,
10974            int callingPid, int callingUid) {
10975        synchronized(this) {
10976            if (DEBUG_SERVICE) Log.v(TAG, "startService: " + service
10977                    + " type=" + resolvedType + " args=" + service.getExtras());
10978
10979            if (caller != null) {
10980                final ProcessRecord callerApp = getRecordForAppLocked(caller);
10981                if (callerApp == null) {
10982                    throw new SecurityException(
10983                            "Unable to find app for caller " + caller
10984                            + " (pid=" + Binder.getCallingPid()
10985                            + ") when starting service " + service);
10986                }
10987            }
10988
10989            ServiceLookupResult res =
10990                retrieveServiceLocked(service, resolvedType,
10991                        callingPid, callingUid);
10992            if (res == null) {
10993                return null;
10994            }
10995            if (res.record == null) {
10996                return new ComponentName("!", res.permission != null
10997                        ? res.permission : "private to package");
10998            }
10999            ServiceRecord r = res.record;
11000            if (unscheduleServiceRestartLocked(r)) {
11001                if (DEBUG_SERVICE) Log.v(TAG, "START SERVICE WHILE RESTART PENDING: "
11002                        + r.shortName);
11003            }
11004            r.startRequested = true;
11005            r.callStart = false;
11006            r.lastStartId++;
11007            if (r.lastStartId < 1) {
11008                r.lastStartId = 1;
11009            }
11010            r.pendingStarts.add(new ServiceRecord.StartItem(r.lastStartId, service));
11011            r.lastActivity = SystemClock.uptimeMillis();
11012            synchronized (r.stats.getBatteryStats()) {
11013                r.stats.startRunningLocked();
11014            }
11015            if (!bringUpServiceLocked(r, service.getFlags(), false)) {
11016                return new ComponentName("!", "Service process is bad");
11017            }
11018            return r.name;
11019        }
11020    }
11021
11022    public ComponentName startService(IApplicationThread caller, Intent service,
11023            String resolvedType) {
11024        // Refuse possible leaked file descriptors
11025        if (service != null && service.hasFileDescriptors() == true) {
11026            throw new IllegalArgumentException("File descriptors passed in Intent");
11027        }
11028
11029        synchronized(this) {
11030            final int callingPid = Binder.getCallingPid();
11031            final int callingUid = Binder.getCallingUid();
11032            final long origId = Binder.clearCallingIdentity();
11033            ComponentName res = startServiceLocked(caller, service,
11034                    resolvedType, callingPid, callingUid);
11035            Binder.restoreCallingIdentity(origId);
11036            return res;
11037        }
11038    }
11039
11040    ComponentName startServiceInPackage(int uid,
11041            Intent service, String resolvedType) {
11042        synchronized(this) {
11043            final long origId = Binder.clearCallingIdentity();
11044            ComponentName res = startServiceLocked(null, service,
11045                    resolvedType, -1, uid);
11046            Binder.restoreCallingIdentity(origId);
11047            return res;
11048        }
11049    }
11050
11051    public int stopService(IApplicationThread caller, Intent service,
11052            String resolvedType) {
11053        // Refuse possible leaked file descriptors
11054        if (service != null && service.hasFileDescriptors() == true) {
11055            throw new IllegalArgumentException("File descriptors passed in Intent");
11056        }
11057
11058        synchronized(this) {
11059            if (DEBUG_SERVICE) Log.v(TAG, "stopService: " + service
11060                    + " type=" + resolvedType);
11061
11062            final ProcessRecord callerApp = getRecordForAppLocked(caller);
11063            if (caller != null && callerApp == null) {
11064                throw new SecurityException(
11065                        "Unable to find app for caller " + caller
11066                        + " (pid=" + Binder.getCallingPid()
11067                        + ") when stopping service " + service);
11068            }
11069
11070            // If this service is active, make sure it is stopped.
11071            ServiceLookupResult r = findServiceLocked(service, resolvedType);
11072            if (r != null) {
11073                if (r.record != null) {
11074                    synchronized (r.record.stats.getBatteryStats()) {
11075                        r.record.stats.stopRunningLocked();
11076                    }
11077                    r.record.startRequested = false;
11078                    r.record.callStart = false;
11079                    final long origId = Binder.clearCallingIdentity();
11080                    bringDownServiceLocked(r.record, false);
11081                    Binder.restoreCallingIdentity(origId);
11082                    return 1;
11083                }
11084                return -1;
11085            }
11086        }
11087
11088        return 0;
11089    }
11090
11091    public IBinder peekService(Intent service, String resolvedType) {
11092        // Refuse possible leaked file descriptors
11093        if (service != null && service.hasFileDescriptors() == true) {
11094            throw new IllegalArgumentException("File descriptors passed in Intent");
11095        }
11096
11097        IBinder ret = null;
11098
11099        synchronized(this) {
11100            ServiceLookupResult r = findServiceLocked(service, resolvedType);
11101
11102            if (r != null) {
11103                // r.record is null if findServiceLocked() failed the caller permission check
11104                if (r.record == null) {
11105                    throw new SecurityException(
11106                            "Permission Denial: Accessing service " + r.record.name
11107                            + " from pid=" + Binder.getCallingPid()
11108                            + ", uid=" + Binder.getCallingUid()
11109                            + " requires " + r.permission);
11110                }
11111                IntentBindRecord ib = r.record.bindings.get(r.record.intent);
11112                if (ib != null) {
11113                    ret = ib.binder;
11114                }
11115            }
11116        }
11117
11118        return ret;
11119    }
11120
11121    public boolean stopServiceToken(ComponentName className, IBinder token,
11122            int startId) {
11123        synchronized(this) {
11124            if (DEBUG_SERVICE) Log.v(TAG, "stopServiceToken: " + className
11125                    + " " + token + " startId=" + startId);
11126            ServiceRecord r = findServiceLocked(className, token);
11127            if (r != null) {
11128                if (startId >= 0) {
11129                    // Asked to only stop if done with all work.  Note that
11130                    // to avoid leaks, we will take this as dropping all
11131                    // start items up to and including this one.
11132                    ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
11133                    if (si != null) {
11134                        while (r.deliveredStarts.size() > 0) {
11135                            if (r.deliveredStarts.remove(0) == si) {
11136                                break;
11137                            }
11138                        }
11139                    }
11140
11141                    if (r.lastStartId != startId) {
11142                        return false;
11143                    }
11144
11145                    if (r.deliveredStarts.size() > 0) {
11146                        Log.w(TAG, "stopServiceToken startId " + startId
11147                                + " is last, but have " + r.deliveredStarts.size()
11148                                + " remaining args");
11149                    }
11150                }
11151
11152                synchronized (r.stats.getBatteryStats()) {
11153                    r.stats.stopRunningLocked();
11154                    r.startRequested = false;
11155                    r.callStart = false;
11156                }
11157                final long origId = Binder.clearCallingIdentity();
11158                bringDownServiceLocked(r, false);
11159                Binder.restoreCallingIdentity(origId);
11160                return true;
11161            }
11162        }
11163        return false;
11164    }
11165
11166    public void setServiceForeground(ComponentName className, IBinder token,
11167            int id, Notification notification, boolean removeNotification) {
11168        final long origId = Binder.clearCallingIdentity();
11169        try {
11170        synchronized(this) {
11171            ServiceRecord r = findServiceLocked(className, token);
11172            if (r != null) {
11173                if (id != 0) {
11174                    if (notification == null) {
11175                        throw new IllegalArgumentException("null notification");
11176                    }
11177                    if (r.foregroundId != id) {
11178                        r.cancelNotification();
11179                        r.foregroundId = id;
11180                    }
11181                    notification.flags |= Notification.FLAG_FOREGROUND_SERVICE;
11182                    r.foregroundNoti = notification;
11183                    r.isForeground = true;
11184                    r.postNotification();
11185                    if (r.app != null) {
11186                        updateServiceForegroundLocked(r.app, true);
11187                    }
11188                } else {
11189                    if (r.isForeground) {
11190                        r.isForeground = false;
11191                        if (r.app != null) {
11192                            updateServiceForegroundLocked(r.app, true);
11193                        }
11194                    }
11195                    if (removeNotification) {
11196                        r.cancelNotification();
11197                        r.foregroundId = 0;
11198                        r.foregroundNoti = null;
11199                    }
11200                }
11201            }
11202        }
11203        } finally {
11204            Binder.restoreCallingIdentity(origId);
11205        }
11206    }
11207
11208    public void updateServiceForegroundLocked(ProcessRecord proc, boolean oomAdj) {
11209        boolean anyForeground = false;
11210        for (ServiceRecord sr : (HashSet<ServiceRecord>)proc.services) {
11211            if (sr.isForeground) {
11212                anyForeground = true;
11213                break;
11214            }
11215        }
11216        if (anyForeground != proc.foregroundServices) {
11217            proc.foregroundServices = anyForeground;
11218            if (oomAdj) {
11219                updateOomAdjLocked();
11220            }
11221        }
11222    }
11223
11224    public int bindService(IApplicationThread caller, IBinder token,
11225            Intent service, String resolvedType,
11226            IServiceConnection connection, int flags) {
11227        // Refuse possible leaked file descriptors
11228        if (service != null && service.hasFileDescriptors() == true) {
11229            throw new IllegalArgumentException("File descriptors passed in Intent");
11230        }
11231
11232        synchronized(this) {
11233            if (DEBUG_SERVICE) Log.v(TAG, "bindService: " + service
11234                    + " type=" + resolvedType + " conn=" + connection.asBinder()
11235                    + " flags=0x" + Integer.toHexString(flags));
11236            final ProcessRecord callerApp = getRecordForAppLocked(caller);
11237            if (callerApp == null) {
11238                throw new SecurityException(
11239                        "Unable to find app for caller " + caller
11240                        + " (pid=" + Binder.getCallingPid()
11241                        + ") when binding service " + service);
11242            }
11243
11244            HistoryRecord activity = null;
11245            if (token != null) {
11246                int aindex = indexOfTokenLocked(token);
11247                if (aindex < 0) {
11248                    Log.w(TAG, "Binding with unknown activity: " + token);
11249                    return 0;
11250                }
11251                activity = (HistoryRecord)mHistory.get(aindex);
11252            }
11253
11254            int clientLabel = 0;
11255            PendingIntent clientIntent = null;
11256
11257            if (callerApp.info.uid == Process.SYSTEM_UID) {
11258                // Hacky kind of thing -- allow system stuff to tell us
11259                // what they are, so we can report this elsewhere for
11260                // others to know why certain services are running.
11261                try {
11262                    clientIntent = (PendingIntent)service.getParcelableExtra(
11263                            Intent.EXTRA_CLIENT_INTENT);
11264                } catch (RuntimeException e) {
11265                }
11266                if (clientIntent != null) {
11267                    clientLabel = service.getIntExtra(Intent.EXTRA_CLIENT_LABEL, 0);
11268                    if (clientLabel != 0) {
11269                        // There are no useful extras in the intent, trash them.
11270                        // System code calling with this stuff just needs to know
11271                        // this will happen.
11272                        service = service.cloneFilter();
11273                    }
11274                }
11275            }
11276
11277            ServiceLookupResult res =
11278                retrieveServiceLocked(service, resolvedType,
11279                        Binder.getCallingPid(), Binder.getCallingUid());
11280            if (res == null) {
11281                return 0;
11282            }
11283            if (res.record == null) {
11284                return -1;
11285            }
11286            ServiceRecord s = res.record;
11287
11288            final long origId = Binder.clearCallingIdentity();
11289
11290            if (unscheduleServiceRestartLocked(s)) {
11291                if (DEBUG_SERVICE) Log.v(TAG, "BIND SERVICE WHILE RESTART PENDING: "
11292                        + s.shortName);
11293            }
11294
11295            AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
11296            ConnectionRecord c = new ConnectionRecord(b, activity,
11297                    connection, flags, clientLabel, clientIntent);
11298
11299            IBinder binder = connection.asBinder();
11300            s.connections.put(binder, c);
11301            b.connections.add(c);
11302            if (activity != null) {
11303                if (activity.connections == null) {
11304                    activity.connections = new HashSet<ConnectionRecord>();
11305                }
11306                activity.connections.add(c);
11307            }
11308            b.client.connections.add(c);
11309            mServiceConnections.put(binder, c);
11310
11311            if ((flags&Context.BIND_AUTO_CREATE) != 0) {
11312                s.lastActivity = SystemClock.uptimeMillis();
11313                if (!bringUpServiceLocked(s, service.getFlags(), false)) {
11314                    return 0;
11315                }
11316            }
11317
11318            if (s.app != null) {
11319                // This could have made the service more important.
11320                updateOomAdjLocked(s.app);
11321            }
11322
11323            if (DEBUG_SERVICE) Log.v(TAG, "Bind " + s + " with " + b
11324                    + ": received=" + b.intent.received
11325                    + " apps=" + b.intent.apps.size()
11326                    + " doRebind=" + b.intent.doRebind);
11327
11328            if (s.app != null && b.intent.received) {
11329                // Service is already running, so we can immediately
11330                // publish the connection.
11331                try {
11332                    c.conn.connected(s.name, b.intent.binder);
11333                } catch (Exception e) {
11334                    Log.w(TAG, "Failure sending service " + s.shortName
11335                            + " to connection " + c.conn.asBinder()
11336                            + " (in " + c.binding.client.processName + ")", e);
11337                }
11338
11339                // If this is the first app connected back to this binding,
11340                // and the service had previously asked to be told when
11341                // rebound, then do so.
11342                if (b.intent.apps.size() == 1 && b.intent.doRebind) {
11343                    requestServiceBindingLocked(s, b.intent, true);
11344                }
11345            } else if (!b.intent.requested) {
11346                requestServiceBindingLocked(s, b.intent, false);
11347            }
11348
11349            Binder.restoreCallingIdentity(origId);
11350        }
11351
11352        return 1;
11353    }
11354
11355    private void removeConnectionLocked(
11356        ConnectionRecord c, ProcessRecord skipApp, HistoryRecord skipAct) {
11357        IBinder binder = c.conn.asBinder();
11358        AppBindRecord b = c.binding;
11359        ServiceRecord s = b.service;
11360        s.connections.remove(binder);
11361        b.connections.remove(c);
11362        if (c.activity != null && c.activity != skipAct) {
11363            if (c.activity.connections != null) {
11364                c.activity.connections.remove(c);
11365            }
11366        }
11367        if (b.client != skipApp) {
11368            b.client.connections.remove(c);
11369        }
11370        mServiceConnections.remove(binder);
11371
11372        if (b.connections.size() == 0) {
11373            b.intent.apps.remove(b.client);
11374        }
11375
11376        if (DEBUG_SERVICE) Log.v(TAG, "Disconnecting binding " + b.intent
11377                + ": shouldUnbind=" + b.intent.hasBound);
11378        if (s.app != null && s.app.thread != null && b.intent.apps.size() == 0
11379                && b.intent.hasBound) {
11380            try {
11381                bumpServiceExecutingLocked(s);
11382                updateOomAdjLocked(s.app);
11383                b.intent.hasBound = false;
11384                // Assume the client doesn't want to know about a rebind;
11385                // we will deal with that later if it asks for one.
11386                b.intent.doRebind = false;
11387                s.app.thread.scheduleUnbindService(s, b.intent.intent.getIntent());
11388            } catch (Exception e) {
11389                Log.w(TAG, "Exception when unbinding service " + s.shortName, e);
11390                serviceDoneExecutingLocked(s, true);
11391            }
11392        }
11393
11394        if ((c.flags&Context.BIND_AUTO_CREATE) != 0) {
11395            bringDownServiceLocked(s, false);
11396        }
11397    }
11398
11399    public boolean unbindService(IServiceConnection connection) {
11400        synchronized (this) {
11401            IBinder binder = connection.asBinder();
11402            if (DEBUG_SERVICE) Log.v(TAG, "unbindService: conn=" + binder);
11403            ConnectionRecord r = mServiceConnections.get(binder);
11404            if (r == null) {
11405                Log.w(TAG, "Unbind failed: could not find connection for "
11406                      + connection.asBinder());
11407                return false;
11408            }
11409
11410            final long origId = Binder.clearCallingIdentity();
11411
11412            removeConnectionLocked(r, null, null);
11413
11414            if (r.binding.service.app != null) {
11415                // This could have made the service less important.
11416                updateOomAdjLocked(r.binding.service.app);
11417            }
11418
11419            Binder.restoreCallingIdentity(origId);
11420        }
11421
11422        return true;
11423    }
11424
11425    public void publishService(IBinder token, Intent intent, IBinder service) {
11426        // Refuse possible leaked file descriptors
11427        if (intent != null && intent.hasFileDescriptors() == true) {
11428            throw new IllegalArgumentException("File descriptors passed in Intent");
11429        }
11430
11431        synchronized(this) {
11432            if (!(token instanceof ServiceRecord)) {
11433                throw new IllegalArgumentException("Invalid service token");
11434            }
11435            ServiceRecord r = (ServiceRecord)token;
11436
11437            final long origId = Binder.clearCallingIdentity();
11438
11439            if (DEBUG_SERVICE) Log.v(TAG, "PUBLISHING SERVICE " + r.name
11440                    + " " + intent + ": " + service);
11441            if (r != null) {
11442                Intent.FilterComparison filter
11443                        = new Intent.FilterComparison(intent);
11444                IntentBindRecord b = r.bindings.get(filter);
11445                if (b != null && !b.received) {
11446                    b.binder = service;
11447                    b.requested = true;
11448                    b.received = true;
11449                    if (r.connections.size() > 0) {
11450                        Iterator<ConnectionRecord> it
11451                                = r.connections.values().iterator();
11452                        while (it.hasNext()) {
11453                            ConnectionRecord c = it.next();
11454                            if (!filter.equals(c.binding.intent.intent)) {
11455                                if (DEBUG_SERVICE) Log.v(
11456                                        TAG, "Not publishing to: " + c);
11457                                if (DEBUG_SERVICE) Log.v(
11458                                        TAG, "Bound intent: " + c.binding.intent.intent);
11459                                if (DEBUG_SERVICE) Log.v(
11460                                        TAG, "Published intent: " + intent);
11461                                continue;
11462                            }
11463                            if (DEBUG_SERVICE) Log.v(TAG, "Publishing to: " + c);
11464                            try {
11465                                c.conn.connected(r.name, service);
11466                            } catch (Exception e) {
11467                                Log.w(TAG, "Failure sending service " + r.name +
11468                                      " to connection " + c.conn.asBinder() +
11469                                      " (in " + c.binding.client.processName + ")", e);
11470                            }
11471                        }
11472                    }
11473                }
11474
11475                serviceDoneExecutingLocked(r, mStoppingServices.contains(r));
11476
11477                Binder.restoreCallingIdentity(origId);
11478            }
11479        }
11480    }
11481
11482    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
11483        // Refuse possible leaked file descriptors
11484        if (intent != null && intent.hasFileDescriptors() == true) {
11485            throw new IllegalArgumentException("File descriptors passed in Intent");
11486        }
11487
11488        synchronized(this) {
11489            if (!(token instanceof ServiceRecord)) {
11490                throw new IllegalArgumentException("Invalid service token");
11491            }
11492            ServiceRecord r = (ServiceRecord)token;
11493
11494            final long origId = Binder.clearCallingIdentity();
11495
11496            if (r != null) {
11497                Intent.FilterComparison filter
11498                        = new Intent.FilterComparison(intent);
11499                IntentBindRecord b = r.bindings.get(filter);
11500                if (DEBUG_SERVICE) Log.v(TAG, "unbindFinished in " + r
11501                        + " at " + b + ": apps="
11502                        + (b != null ? b.apps.size() : 0));
11503                if (b != null) {
11504                    if (b.apps.size() > 0) {
11505                        // Applications have already bound since the last
11506                        // unbind, so just rebind right here.
11507                        requestServiceBindingLocked(r, b, true);
11508                    } else {
11509                        // Note to tell the service the next time there is
11510                        // a new client.
11511                        b.doRebind = true;
11512                    }
11513                }
11514
11515                serviceDoneExecutingLocked(r, mStoppingServices.contains(r));
11516
11517                Binder.restoreCallingIdentity(origId);
11518            }
11519        }
11520    }
11521
11522    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
11523        synchronized(this) {
11524            if (!(token instanceof ServiceRecord)) {
11525                throw new IllegalArgumentException("Invalid service token");
11526            }
11527            ServiceRecord r = (ServiceRecord)token;
11528            boolean inStopping = mStoppingServices.contains(token);
11529            if (r != null) {
11530                if (DEBUG_SERVICE) Log.v(TAG, "DONE EXECUTING SERVICE " + r.name
11531                        + ": nesting=" + r.executeNesting
11532                        + ", inStopping=" + inStopping);
11533                if (r != token) {
11534                    Log.w(TAG, "Done executing service " + r.name
11535                          + " with incorrect token: given " + token
11536                          + ", expected " + r);
11537                    return;
11538                }
11539
11540                if (type == 1) {
11541                    // This is a call from a service start...  take care of
11542                    // book-keeping.
11543                    r.callStart = true;
11544                    switch (res) {
11545                        case Service.START_STICKY_COMPATIBILITY:
11546                        case Service.START_STICKY: {
11547                            // We are done with the associated start arguments.
11548                            r.findDeliveredStart(startId, true);
11549                            // Don't stop if killed.
11550                            r.stopIfKilled = false;
11551                            break;
11552                        }
11553                        case Service.START_NOT_STICKY: {
11554                            // We are done with the associated start arguments.
11555                            r.findDeliveredStart(startId, true);
11556                            if (r.lastStartId == startId) {
11557                                // There is no more work, and this service
11558                                // doesn't want to hang around if killed.
11559                                r.stopIfKilled = true;
11560                            }
11561                            break;
11562                        }
11563                        case Service.START_REDELIVER_INTENT: {
11564                            // We'll keep this item until they explicitly
11565                            // call stop for it, but keep track of the fact
11566                            // that it was delivered.
11567                            ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
11568                            if (si != null) {
11569                                si.deliveryCount = 0;
11570                                si.doneExecutingCount++;
11571                                // Don't stop if killed.
11572                                r.stopIfKilled = true;
11573                            }
11574                            break;
11575                        }
11576                        default:
11577                            throw new IllegalArgumentException(
11578                                    "Unknown service start result: " + res);
11579                    }
11580                    if (res == Service.START_STICKY_COMPATIBILITY) {
11581                        r.callStart = false;
11582                    }
11583                }
11584
11585                final long origId = Binder.clearCallingIdentity();
11586                serviceDoneExecutingLocked(r, inStopping);
11587                Binder.restoreCallingIdentity(origId);
11588            } else {
11589                Log.w(TAG, "Done executing unknown service " + r.name
11590                        + " with token " + token);
11591            }
11592        }
11593    }
11594
11595    public void serviceDoneExecutingLocked(ServiceRecord r, boolean inStopping) {
11596        r.executeNesting--;
11597        if (r.executeNesting <= 0 && r.app != null) {
11598            r.app.executingServices.remove(r);
11599            if (r.app.executingServices.size() == 0) {
11600                mHandler.removeMessages(SERVICE_TIMEOUT_MSG, r.app);
11601            }
11602            if (inStopping) {
11603                mStoppingServices.remove(r);
11604            }
11605            updateOomAdjLocked(r.app);
11606        }
11607    }
11608
11609    void serviceTimeout(ProcessRecord proc) {
11610        synchronized(this) {
11611            if (proc.executingServices.size() == 0 || proc.thread == null) {
11612                return;
11613            }
11614            long maxTime = SystemClock.uptimeMillis() - SERVICE_TIMEOUT;
11615            Iterator<ServiceRecord> it = proc.executingServices.iterator();
11616            ServiceRecord timeout = null;
11617            long nextTime = 0;
11618            while (it.hasNext()) {
11619                ServiceRecord sr = it.next();
11620                if (sr.executingStart < maxTime) {
11621                    timeout = sr;
11622                    break;
11623                }
11624                if (sr.executingStart > nextTime) {
11625                    nextTime = sr.executingStart;
11626                }
11627            }
11628            if (timeout != null && mLruProcesses.contains(proc)) {
11629                Log.w(TAG, "Timeout executing service: " + timeout);
11630                appNotRespondingLocked(proc, null, null, "Executing service " + timeout.shortName);
11631            } else {
11632                Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
11633                msg.obj = proc;
11634                mHandler.sendMessageAtTime(msg, nextTime+SERVICE_TIMEOUT);
11635            }
11636        }
11637    }
11638
11639    // =========================================================
11640    // BACKUP AND RESTORE
11641    // =========================================================
11642
11643    // Cause the target app to be launched if necessary and its backup agent
11644    // instantiated.  The backup agent will invoke backupAgentCreated() on the
11645    // activity manager to announce its creation.
11646    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
11647        if (DEBUG_BACKUP) Log.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode);
11648        enforceCallingPermission("android.permission.BACKUP", "startBackupAgent");
11649
11650        synchronized(this) {
11651            // !!! TODO: currently no check here that we're already bound
11652            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
11653            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11654            synchronized (stats) {
11655                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
11656            }
11657
11658            BackupRecord r = new BackupRecord(ss, app, backupMode);
11659            ComponentName hostingName = new ComponentName(app.packageName, app.backupAgentName);
11660            // startProcessLocked() returns existing proc's record if it's already running
11661            ProcessRecord proc = startProcessLocked(app.processName, app,
11662                    false, 0, "backup", hostingName, false);
11663            if (proc == null) {
11664                Log.e(TAG, "Unable to start backup agent process " + r);
11665                return false;
11666            }
11667
11668            r.app = proc;
11669            mBackupTarget = r;
11670            mBackupAppName = app.packageName;
11671
11672            // Try not to kill the process during backup
11673            updateOomAdjLocked(proc);
11674
11675            // If the process is already attached, schedule the creation of the backup agent now.
11676            // If it is not yet live, this will be done when it attaches to the framework.
11677            if (proc.thread != null) {
11678                if (DEBUG_BACKUP) Log.v(TAG, "Agent proc already running: " + proc);
11679                try {
11680                    proc.thread.scheduleCreateBackupAgent(app, backupMode);
11681                } catch (RemoteException e) {
11682                    // Will time out on the backup manager side
11683                }
11684            } else {
11685                if (DEBUG_BACKUP) Log.v(TAG, "Agent proc not running, waiting for attach");
11686            }
11687            // Invariants: at this point, the target app process exists and the application
11688            // is either already running or in the process of coming up.  mBackupTarget and
11689            // mBackupAppName describe the app, so that when it binds back to the AM we
11690            // know that it's scheduled for a backup-agent operation.
11691        }
11692
11693        return true;
11694    }
11695
11696    // A backup agent has just come up
11697    public void backupAgentCreated(String agentPackageName, IBinder agent) {
11698        if (DEBUG_BACKUP) Log.v(TAG, "backupAgentCreated: " + agentPackageName
11699                + " = " + agent);
11700
11701        synchronized(this) {
11702            if (!agentPackageName.equals(mBackupAppName)) {
11703                Log.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
11704                return;
11705            }
11706
11707            long oldIdent = Binder.clearCallingIdentity();
11708            try {
11709                IBackupManager bm = IBackupManager.Stub.asInterface(
11710                        ServiceManager.getService(Context.BACKUP_SERVICE));
11711                bm.agentConnected(agentPackageName, agent);
11712            } catch (RemoteException e) {
11713                // can't happen; the backup manager service is local
11714            } catch (Exception e) {
11715                Log.w(TAG, "Exception trying to deliver BackupAgent binding: ");
11716                e.printStackTrace();
11717            } finally {
11718                Binder.restoreCallingIdentity(oldIdent);
11719            }
11720        }
11721    }
11722
11723    // done with this agent
11724    public void unbindBackupAgent(ApplicationInfo appInfo) {
11725        if (DEBUG_BACKUP) Log.v(TAG, "unbindBackupAgent: " + appInfo);
11726        if (appInfo == null) {
11727            Log.w(TAG, "unbind backup agent for null app");
11728            return;
11729        }
11730
11731        synchronized(this) {
11732            if (mBackupAppName == null) {
11733                Log.w(TAG, "Unbinding backup agent with no active backup");
11734                return;
11735            }
11736
11737            if (!mBackupAppName.equals(appInfo.packageName)) {
11738                Log.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
11739                return;
11740            }
11741
11742            ProcessRecord proc = mBackupTarget.app;
11743            mBackupTarget = null;
11744            mBackupAppName = null;
11745
11746            // Not backing this app up any more; reset its OOM adjustment
11747            updateOomAdjLocked(proc);
11748
11749            // If the app crashed during backup, 'thread' will be null here
11750            if (proc.thread != null) {
11751                try {
11752                    proc.thread.scheduleDestroyBackupAgent(appInfo);
11753                } catch (Exception e) {
11754                    Log.e(TAG, "Exception when unbinding backup agent:");
11755                    e.printStackTrace();
11756                }
11757            }
11758        }
11759    }
11760    // =========================================================
11761    // BROADCASTS
11762    // =========================================================
11763
11764    private final List getStickies(String action, IntentFilter filter,
11765            List cur) {
11766        final ContentResolver resolver = mContext.getContentResolver();
11767        final ArrayList<Intent> list = mStickyBroadcasts.get(action);
11768        if (list == null) {
11769            return cur;
11770        }
11771        int N = list.size();
11772        for (int i=0; i<N; i++) {
11773            Intent intent = list.get(i);
11774            if (filter.match(resolver, intent, true, TAG) >= 0) {
11775                if (cur == null) {
11776                    cur = new ArrayList<Intent>();
11777                }
11778                cur.add(intent);
11779            }
11780        }
11781        return cur;
11782    }
11783
11784    private final void scheduleBroadcastsLocked() {
11785        if (DEBUG_BROADCAST) Log.v(TAG, "Schedule broadcasts: current="
11786                + mBroadcastsScheduled);
11787
11788        if (mBroadcastsScheduled) {
11789            return;
11790        }
11791        mHandler.sendEmptyMessage(BROADCAST_INTENT_MSG);
11792        mBroadcastsScheduled = true;
11793    }
11794
11795    public Intent registerReceiver(IApplicationThread caller,
11796            IIntentReceiver receiver, IntentFilter filter, String permission) {
11797        synchronized(this) {
11798            ProcessRecord callerApp = null;
11799            if (caller != null) {
11800                callerApp = getRecordForAppLocked(caller);
11801                if (callerApp == null) {
11802                    throw new SecurityException(
11803                            "Unable to find app for caller " + caller
11804                            + " (pid=" + Binder.getCallingPid()
11805                            + ") when registering receiver " + receiver);
11806                }
11807            }
11808
11809            List allSticky = null;
11810
11811            // Look for any matching sticky broadcasts...
11812            Iterator actions = filter.actionsIterator();
11813            if (actions != null) {
11814                while (actions.hasNext()) {
11815                    String action = (String)actions.next();
11816                    allSticky = getStickies(action, filter, allSticky);
11817                }
11818            } else {
11819                allSticky = getStickies(null, filter, allSticky);
11820            }
11821
11822            // The first sticky in the list is returned directly back to
11823            // the client.
11824            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
11825
11826            if (DEBUG_BROADCAST) Log.v(TAG, "Register receiver " + filter
11827                    + ": " + sticky);
11828
11829            if (receiver == null) {
11830                return sticky;
11831            }
11832
11833            ReceiverList rl
11834                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11835            if (rl == null) {
11836                rl = new ReceiverList(this, callerApp,
11837                        Binder.getCallingPid(),
11838                        Binder.getCallingUid(), receiver);
11839                if (rl.app != null) {
11840                    rl.app.receivers.add(rl);
11841                } else {
11842                    try {
11843                        receiver.asBinder().linkToDeath(rl, 0);
11844                    } catch (RemoteException e) {
11845                        return sticky;
11846                    }
11847                    rl.linkedToDeath = true;
11848                }
11849                mRegisteredReceivers.put(receiver.asBinder(), rl);
11850            }
11851            BroadcastFilter bf = new BroadcastFilter(filter, rl, permission);
11852            rl.add(bf);
11853            if (!bf.debugCheck()) {
11854                Log.w(TAG, "==> For Dynamic broadast");
11855            }
11856            mReceiverResolver.addFilter(bf);
11857
11858            // Enqueue broadcasts for all existing stickies that match
11859            // this filter.
11860            if (allSticky != null) {
11861                ArrayList receivers = new ArrayList();
11862                receivers.add(bf);
11863
11864                int N = allSticky.size();
11865                for (int i=0; i<N; i++) {
11866                    Intent intent = (Intent)allSticky.get(i);
11867                    BroadcastRecord r = new BroadcastRecord(intent, null,
11868                            null, -1, -1, null, receivers, null, 0, null, null,
11869                            false, true, true);
11870                    if (mParallelBroadcasts.size() == 0) {
11871                        scheduleBroadcastsLocked();
11872                    }
11873                    mParallelBroadcasts.add(r);
11874                }
11875            }
11876
11877            return sticky;
11878        }
11879    }
11880
11881    public void unregisterReceiver(IIntentReceiver receiver) {
11882        if (DEBUG_BROADCAST) Log.v(TAG, "Unregister receiver: " + receiver);
11883
11884        boolean doNext = false;
11885
11886        synchronized(this) {
11887            ReceiverList rl
11888                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11889            if (rl != null) {
11890                if (rl.curBroadcast != null) {
11891                    BroadcastRecord r = rl.curBroadcast;
11892                    doNext = finishReceiverLocked(
11893                        receiver.asBinder(), r.resultCode, r.resultData,
11894                        r.resultExtras, r.resultAbort, true);
11895                }
11896
11897                if (rl.app != null) {
11898                    rl.app.receivers.remove(rl);
11899                }
11900                removeReceiverLocked(rl);
11901                if (rl.linkedToDeath) {
11902                    rl.linkedToDeath = false;
11903                    rl.receiver.asBinder().unlinkToDeath(rl, 0);
11904                }
11905            }
11906        }
11907
11908        if (!doNext) {
11909            return;
11910        }
11911
11912        final long origId = Binder.clearCallingIdentity();
11913        processNextBroadcast(false);
11914        trimApplications();
11915        Binder.restoreCallingIdentity(origId);
11916    }
11917
11918    void removeReceiverLocked(ReceiverList rl) {
11919        mRegisteredReceivers.remove(rl.receiver.asBinder());
11920        int N = rl.size();
11921        for (int i=0; i<N; i++) {
11922            mReceiverResolver.removeFilter(rl.get(i));
11923        }
11924    }
11925
11926    private final int broadcastIntentLocked(ProcessRecord callerApp,
11927            String callerPackage, Intent intent, String resolvedType,
11928            IIntentReceiver resultTo, int resultCode, String resultData,
11929            Bundle map, String requiredPermission,
11930            boolean ordered, boolean sticky, int callingPid, int callingUid) {
11931        intent = new Intent(intent);
11932
11933        if (DEBUG_BROADCAST_LIGHT) Log.v(
11934            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
11935            + " ordered=" + ordered);
11936        if ((resultTo != null) && !ordered) {
11937            Log.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
11938        }
11939
11940        // Handle special intents: if this broadcast is from the package
11941        // manager about a package being removed, we need to remove all of
11942        // its activities from the history stack.
11943        final boolean uidRemoved = intent.ACTION_UID_REMOVED.equals(
11944                intent.getAction());
11945        if (intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
11946                || intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
11947                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
11948                || uidRemoved) {
11949            if (checkComponentPermission(
11950                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
11951                    callingPid, callingUid, -1)
11952                    == PackageManager.PERMISSION_GRANTED) {
11953                if (uidRemoved) {
11954                    final Bundle intentExtras = intent.getExtras();
11955                    final int uid = intentExtras != null
11956                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
11957                    if (uid >= 0) {
11958                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
11959                        synchronized (bs) {
11960                            bs.removeUidStatsLocked(uid);
11961                        }
11962                    }
11963                } else {
11964                    // If resources are unvailble just force stop all
11965                    // those packages and flush the attribute cache as well.
11966                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
11967                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
11968                        if (list != null && (list.length > 0)) {
11969                            for (String pkg : list) {
11970                                forceStopPackageLocked(pkg, -1, false, true);
11971                            }
11972                        }
11973                    } else {
11974                        Uri data = intent.getData();
11975                        String ssp;
11976                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11977                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
11978                                forceStopPackageLocked(ssp,
11979                                        intent.getIntExtra(Intent.EXTRA_UID, -1), false, true);
11980                            }
11981                        }
11982                    }
11983                }
11984            } else {
11985                String msg = "Permission Denial: " + intent.getAction()
11986                        + " broadcast from " + callerPackage + " (pid=" + callingPid
11987                        + ", uid=" + callingUid + ")"
11988                        + " requires "
11989                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
11990                Log.w(TAG, msg);
11991                throw new SecurityException(msg);
11992            }
11993        }
11994
11995        /*
11996         * If this is the time zone changed action, queue up a message that will reset the timezone
11997         * of all currently running processes. This message will get queued up before the broadcast
11998         * happens.
11999         */
12000        if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
12001            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
12002        }
12003
12004        /*
12005         * Prevent non-system code (defined here to be non-persistent
12006         * processes) from sending protected broadcasts.
12007         */
12008        if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID
12009                || callingUid == Process.SHELL_UID || callingUid == 0) {
12010            // Always okay.
12011        } else if (callerApp == null || !callerApp.persistent) {
12012            try {
12013                if (ActivityThread.getPackageManager().isProtectedBroadcast(
12014                        intent.getAction())) {
12015                    String msg = "Permission Denial: not allowed to send broadcast "
12016                            + intent.getAction() + " from pid="
12017                            + callingPid + ", uid=" + callingUid;
12018                    Log.w(TAG, msg);
12019                    throw new SecurityException(msg);
12020                }
12021            } catch (RemoteException e) {
12022                Log.w(TAG, "Remote exception", e);
12023                return BROADCAST_SUCCESS;
12024            }
12025        }
12026
12027        // Add to the sticky list if requested.
12028        if (sticky) {
12029            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
12030                    callingPid, callingUid)
12031                    != PackageManager.PERMISSION_GRANTED) {
12032                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
12033                        + callingPid + ", uid=" + callingUid
12034                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
12035                Log.w(TAG, msg);
12036                throw new SecurityException(msg);
12037            }
12038            if (requiredPermission != null) {
12039                Log.w(TAG, "Can't broadcast sticky intent " + intent
12040                        + " and enforce permission " + requiredPermission);
12041                return BROADCAST_STICKY_CANT_HAVE_PERMISSION;
12042            }
12043            if (intent.getComponent() != null) {
12044                throw new SecurityException(
12045                        "Sticky broadcasts can't target a specific component");
12046            }
12047            ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
12048            if (list == null) {
12049                list = new ArrayList<Intent>();
12050                mStickyBroadcasts.put(intent.getAction(), list);
12051            }
12052            int N = list.size();
12053            int i;
12054            for (i=0; i<N; i++) {
12055                if (intent.filterEquals(list.get(i))) {
12056                    // This sticky already exists, replace it.
12057                    list.set(i, new Intent(intent));
12058                    break;
12059                }
12060            }
12061            if (i >= N) {
12062                list.add(new Intent(intent));
12063            }
12064        }
12065
12066        // Figure out who all will receive this broadcast.
12067        List receivers = null;
12068        List<BroadcastFilter> registeredReceivers = null;
12069        try {
12070            if (intent.getComponent() != null) {
12071                // Broadcast is going to one specific receiver class...
12072                ActivityInfo ai = ActivityThread.getPackageManager().
12073                    getReceiverInfo(intent.getComponent(), STOCK_PM_FLAGS);
12074                if (ai != null) {
12075                    receivers = new ArrayList();
12076                    ResolveInfo ri = new ResolveInfo();
12077                    ri.activityInfo = ai;
12078                    receivers.add(ri);
12079                }
12080            } else {
12081                // Need to resolve the intent to interested receivers...
12082                if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
12083                         == 0) {
12084                    receivers =
12085                        ActivityThread.getPackageManager().queryIntentReceivers(
12086                                intent, resolvedType, STOCK_PM_FLAGS);
12087                }
12088                registeredReceivers = mReceiverResolver.queryIntent(intent, resolvedType, false);
12089            }
12090        } catch (RemoteException ex) {
12091            // pm is in same process, this will never happen.
12092        }
12093
12094        final boolean replacePending =
12095                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
12096
12097        if (DEBUG_BROADCAST) Log.v(TAG, "Enqueing broadcast: " + intent.getAction()
12098                + " replacePending=" + replacePending);
12099
12100        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
12101        if (!ordered && NR > 0) {
12102            // If we are not serializing this broadcast, then send the
12103            // registered receivers separately so they don't wait for the
12104            // components to be launched.
12105            BroadcastRecord r = new BroadcastRecord(intent, callerApp,
12106                    callerPackage, callingPid, callingUid, requiredPermission,
12107                    registeredReceivers, resultTo, resultCode, resultData, map,
12108                    ordered, sticky, false);
12109            if (DEBUG_BROADCAST) Log.v(
12110                    TAG, "Enqueueing parallel broadcast " + r
12111                    + ": prev had " + mParallelBroadcasts.size());
12112            boolean replaced = false;
12113            if (replacePending) {
12114                for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
12115                    if (intent.filterEquals(mParallelBroadcasts.get(i).intent)) {
12116                        if (DEBUG_BROADCAST) Log.v(TAG,
12117                                "***** DROPPING PARALLEL: " + intent);
12118                        mParallelBroadcasts.set(i, r);
12119                        replaced = true;
12120                        break;
12121                    }
12122                }
12123            }
12124            if (!replaced) {
12125                mParallelBroadcasts.add(r);
12126                scheduleBroadcastsLocked();
12127            }
12128            registeredReceivers = null;
12129            NR = 0;
12130        }
12131
12132        // Merge into one list.
12133        int ir = 0;
12134        if (receivers != null) {
12135            // A special case for PACKAGE_ADDED: do not allow the package
12136            // being added to see this broadcast.  This prevents them from
12137            // using this as a back door to get run as soon as they are
12138            // installed.  Maybe in the future we want to have a special install
12139            // broadcast or such for apps, but we'd like to deliberately make
12140            // this decision.
12141            String skipPackages[] = null;
12142            if (intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
12143                    || intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
12144                    || intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
12145                Uri data = intent.getData();
12146                if (data != null) {
12147                    String pkgName = data.getSchemeSpecificPart();
12148                    if (pkgName != null) {
12149                        skipPackages = new String[] { pkgName };
12150                    }
12151                }
12152            } else if (intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
12153                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
12154            }
12155            if (skipPackages != null && (skipPackages.length > 0)) {
12156                for (String skipPackage : skipPackages) {
12157                    if (skipPackage != null) {
12158                        int NT = receivers.size();
12159                        for (int it=0; it<NT; it++) {
12160                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
12161                            if (curt.activityInfo.packageName.equals(skipPackage)) {
12162                                receivers.remove(it);
12163                                it--;
12164                                NT--;
12165                            }
12166                        }
12167                    }
12168                }
12169            }
12170
12171            int NT = receivers != null ? receivers.size() : 0;
12172            int it = 0;
12173            ResolveInfo curt = null;
12174            BroadcastFilter curr = null;
12175            while (it < NT && ir < NR) {
12176                if (curt == null) {
12177                    curt = (ResolveInfo)receivers.get(it);
12178                }
12179                if (curr == null) {
12180                    curr = registeredReceivers.get(ir);
12181                }
12182                if (curr.getPriority() >= curt.priority) {
12183                    // Insert this broadcast record into the final list.
12184                    receivers.add(it, curr);
12185                    ir++;
12186                    curr = null;
12187                    it++;
12188                    NT++;
12189                } else {
12190                    // Skip to the next ResolveInfo in the final list.
12191                    it++;
12192                    curt = null;
12193                }
12194            }
12195        }
12196        while (ir < NR) {
12197            if (receivers == null) {
12198                receivers = new ArrayList();
12199            }
12200            receivers.add(registeredReceivers.get(ir));
12201            ir++;
12202        }
12203
12204        if ((receivers != null && receivers.size() > 0)
12205                || resultTo != null) {
12206            BroadcastRecord r = new BroadcastRecord(intent, callerApp,
12207                    callerPackage, callingPid, callingUid, requiredPermission,
12208                    receivers, resultTo, resultCode, resultData, map, ordered,
12209                    sticky, false);
12210            if (DEBUG_BROADCAST) Log.v(
12211                    TAG, "Enqueueing ordered broadcast " + r
12212                    + ": prev had " + mOrderedBroadcasts.size());
12213            if (DEBUG_BROADCAST) {
12214                int seq = r.intent.getIntExtra("seq", -1);
12215                Log.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
12216            }
12217            boolean replaced = false;
12218            if (replacePending) {
12219                for (int i=mOrderedBroadcasts.size()-1; i>=0; i--) {
12220                    if (intent.filterEquals(mOrderedBroadcasts.get(i).intent)) {
12221                        if (DEBUG_BROADCAST) Log.v(TAG,
12222                                "***** DROPPING ORDERED: " + intent);
12223                        mOrderedBroadcasts.set(i, r);
12224                        replaced = true;
12225                        break;
12226                    }
12227                }
12228            }
12229            if (!replaced) {
12230                mOrderedBroadcasts.add(r);
12231                scheduleBroadcastsLocked();
12232            }
12233        }
12234
12235        return BROADCAST_SUCCESS;
12236    }
12237
12238    public final int broadcastIntent(IApplicationThread caller,
12239            Intent intent, String resolvedType, IIntentReceiver resultTo,
12240            int resultCode, String resultData, Bundle map,
12241            String requiredPermission, boolean serialized, boolean sticky) {
12242        // Refuse possible leaked file descriptors
12243        if (intent != null && intent.hasFileDescriptors() == true) {
12244            throw new IllegalArgumentException("File descriptors passed in Intent");
12245        }
12246
12247        synchronized(this) {
12248            int flags = intent.getFlags();
12249
12250            if (!mSystemReady) {
12251                // if the caller really truly claims to know what they're doing, go
12252                // ahead and allow the broadcast without launching any receivers
12253                if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
12254                    intent = new Intent(intent);
12255                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
12256                } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0){
12257                    Log.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
12258                            + " before boot completion");
12259                    throw new IllegalStateException("Cannot broadcast before boot completed");
12260                }
12261            }
12262
12263            if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
12264                throw new IllegalArgumentException(
12265                        "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
12266            }
12267
12268            final ProcessRecord callerApp = getRecordForAppLocked(caller);
12269            final int callingPid = Binder.getCallingPid();
12270            final int callingUid = Binder.getCallingUid();
12271            final long origId = Binder.clearCallingIdentity();
12272            int res = broadcastIntentLocked(callerApp,
12273                    callerApp != null ? callerApp.info.packageName : null,
12274                    intent, resolvedType, resultTo,
12275                    resultCode, resultData, map, requiredPermission, serialized,
12276                    sticky, callingPid, callingUid);
12277            Binder.restoreCallingIdentity(origId);
12278            return res;
12279        }
12280    }
12281
12282    int broadcastIntentInPackage(String packageName, int uid,
12283            Intent intent, String resolvedType, IIntentReceiver resultTo,
12284            int resultCode, String resultData, Bundle map,
12285            String requiredPermission, boolean serialized, boolean sticky) {
12286        synchronized(this) {
12287            final long origId = Binder.clearCallingIdentity();
12288            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
12289                    resultTo, resultCode, resultData, map, requiredPermission,
12290                    serialized, sticky, -1, uid);
12291            Binder.restoreCallingIdentity(origId);
12292            return res;
12293        }
12294    }
12295
12296    public final void unbroadcastIntent(IApplicationThread caller,
12297            Intent intent) {
12298        // Refuse possible leaked file descriptors
12299        if (intent != null && intent.hasFileDescriptors() == true) {
12300            throw new IllegalArgumentException("File descriptors passed in Intent");
12301        }
12302
12303        synchronized(this) {
12304            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
12305                    != PackageManager.PERMISSION_GRANTED) {
12306                String msg = "Permission Denial: unbroadcastIntent() from pid="
12307                        + Binder.getCallingPid()
12308                        + ", uid=" + Binder.getCallingUid()
12309                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
12310                Log.w(TAG, msg);
12311                throw new SecurityException(msg);
12312            }
12313            ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
12314            if (list != null) {
12315                int N = list.size();
12316                int i;
12317                for (i=0; i<N; i++) {
12318                    if (intent.filterEquals(list.get(i))) {
12319                        list.remove(i);
12320                        break;
12321                    }
12322                }
12323            }
12324        }
12325    }
12326
12327    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
12328            String resultData, Bundle resultExtras, boolean resultAbort,
12329            boolean explicit) {
12330        if (mOrderedBroadcasts.size() == 0) {
12331            if (explicit) {
12332                Log.w(TAG, "finishReceiver called but no pending broadcasts");
12333            }
12334            return false;
12335        }
12336        BroadcastRecord r = mOrderedBroadcasts.get(0);
12337        if (r.receiver == null) {
12338            if (explicit) {
12339                Log.w(TAG, "finishReceiver called but none active");
12340            }
12341            return false;
12342        }
12343        if (r.receiver != receiver) {
12344            Log.w(TAG, "finishReceiver called but active receiver is different");
12345            return false;
12346        }
12347        int state = r.state;
12348        r.state = r.IDLE;
12349        if (state == r.IDLE) {
12350            if (explicit) {
12351                Log.w(TAG, "finishReceiver called but state is IDLE");
12352            }
12353        }
12354        r.receiver = null;
12355        r.intent.setComponent(null);
12356        if (r.curApp != null) {
12357            r.curApp.curReceiver = null;
12358        }
12359        if (r.curFilter != null) {
12360            r.curFilter.receiverList.curBroadcast = null;
12361        }
12362        r.curFilter = null;
12363        r.curApp = null;
12364        r.curComponent = null;
12365        r.curReceiver = null;
12366        mPendingBroadcast = null;
12367
12368        r.resultCode = resultCode;
12369        r.resultData = resultData;
12370        r.resultExtras = resultExtras;
12371        r.resultAbort = resultAbort;
12372
12373        // We will process the next receiver right now if this is finishing
12374        // an app receiver (which is always asynchronous) or after we have
12375        // come back from calling a receiver.
12376        return state == BroadcastRecord.APP_RECEIVE
12377                || state == BroadcastRecord.CALL_DONE_RECEIVE;
12378    }
12379
12380    public void finishReceiver(IBinder who, int resultCode, String resultData,
12381            Bundle resultExtras, boolean resultAbort) {
12382        if (DEBUG_BROADCAST) Log.v(TAG, "Finish receiver: " + who);
12383
12384        // Refuse possible leaked file descriptors
12385        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
12386            throw new IllegalArgumentException("File descriptors passed in Bundle");
12387        }
12388
12389        boolean doNext;
12390
12391        final long origId = Binder.clearCallingIdentity();
12392
12393        synchronized(this) {
12394            doNext = finishReceiverLocked(
12395                who, resultCode, resultData, resultExtras, resultAbort, true);
12396        }
12397
12398        if (doNext) {
12399            processNextBroadcast(false);
12400        }
12401        trimApplications();
12402
12403        Binder.restoreCallingIdentity(origId);
12404    }
12405
12406    private final void logBroadcastReceiverDiscard(BroadcastRecord r) {
12407        if (r.nextReceiver > 0) {
12408            Object curReceiver = r.receivers.get(r.nextReceiver-1);
12409            if (curReceiver instanceof BroadcastFilter) {
12410                BroadcastFilter bf = (BroadcastFilter) curReceiver;
12411                EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_FILTER,
12412                        System.identityHashCode(r),
12413                        r.intent.getAction(),
12414                        r.nextReceiver - 1,
12415                        System.identityHashCode(bf));
12416            } else {
12417                EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
12418                        System.identityHashCode(r),
12419                        r.intent.getAction(),
12420                        r.nextReceiver - 1,
12421                        ((ResolveInfo)curReceiver).toString());
12422            }
12423        } else {
12424            Log.w(TAG, "Discarding broadcast before first receiver is invoked: "
12425                    + r);
12426            EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
12427                    System.identityHashCode(r),
12428                    r.intent.getAction(),
12429                    r.nextReceiver,
12430                    "NONE");
12431        }
12432    }
12433
12434    private final void broadcastTimeout() {
12435        synchronized (this) {
12436            if (mOrderedBroadcasts.size() == 0) {
12437                return;
12438            }
12439            long now = SystemClock.uptimeMillis();
12440            BroadcastRecord r = mOrderedBroadcasts.get(0);
12441            if ((r.receiverTime+BROADCAST_TIMEOUT) > now) {
12442                if (DEBUG_BROADCAST) Log.v(TAG,
12443                        "Premature timeout @ " + now + ": resetting BROADCAST_TIMEOUT_MSG for "
12444                        + (r.receiverTime + BROADCAST_TIMEOUT));
12445                Message msg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG);
12446                mHandler.sendMessageAtTime(msg, r.receiverTime+BROADCAST_TIMEOUT);
12447                return;
12448            }
12449
12450            Log.w(TAG, "Timeout of broadcast " + r + " - receiver=" + r.receiver);
12451            r.receiverTime = now;
12452            r.anrCount++;
12453
12454            // Current receiver has passed its expiration date.
12455            if (r.nextReceiver <= 0) {
12456                Log.w(TAG, "Timeout on receiver with nextReceiver <= 0");
12457                return;
12458            }
12459
12460            ProcessRecord app = null;
12461
12462            Object curReceiver = r.receivers.get(r.nextReceiver-1);
12463            Log.w(TAG, "Receiver during timeout: " + curReceiver);
12464            logBroadcastReceiverDiscard(r);
12465            if (curReceiver instanceof BroadcastFilter) {
12466                BroadcastFilter bf = (BroadcastFilter)curReceiver;
12467                if (bf.receiverList.pid != 0
12468                        && bf.receiverList.pid != MY_PID) {
12469                    synchronized (this.mPidsSelfLocked) {
12470                        app = this.mPidsSelfLocked.get(
12471                                bf.receiverList.pid);
12472                    }
12473                }
12474            } else {
12475                app = r.curApp;
12476            }
12477
12478            if (app != null) {
12479                appNotRespondingLocked(app, null, null, "Broadcast of " + r.intent.toString());
12480            }
12481
12482            if (mPendingBroadcast == r) {
12483                mPendingBroadcast = null;
12484            }
12485
12486            // Move on to the next receiver.
12487            finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
12488                    r.resultExtras, r.resultAbort, true);
12489            scheduleBroadcastsLocked();
12490        }
12491    }
12492
12493    private final void processCurBroadcastLocked(BroadcastRecord r,
12494            ProcessRecord app) throws RemoteException {
12495        if (app.thread == null) {
12496            throw new RemoteException();
12497        }
12498        r.receiver = app.thread.asBinder();
12499        r.curApp = app;
12500        app.curReceiver = r;
12501        updateLruProcessLocked(app, true, true);
12502
12503        // Tell the application to launch this receiver.
12504        r.intent.setComponent(r.curComponent);
12505
12506        boolean started = false;
12507        try {
12508            if (DEBUG_BROADCAST_LIGHT) Log.v(TAG,
12509                    "Delivering to component " + r.curComponent
12510                    + ": " + r);
12511            ensurePackageDexOpt(r.intent.getComponent().getPackageName());
12512            app.thread.scheduleReceiver(new Intent(r.intent), r.curReceiver,
12513                    r.resultCode, r.resultData, r.resultExtras, r.ordered);
12514            started = true;
12515        } finally {
12516            if (!started) {
12517                r.receiver = null;
12518                r.curApp = null;
12519                app.curReceiver = null;
12520            }
12521        }
12522
12523    }
12524
12525    static void performReceive(ProcessRecord app, IIntentReceiver receiver,
12526            Intent intent, int resultCode, String data, Bundle extras,
12527            boolean ordered, boolean sticky) throws RemoteException {
12528        if (app != null && app.thread != null) {
12529            // If we have an app thread, do the call through that so it is
12530            // correctly ordered with other one-way calls.
12531            app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
12532                    data, extras, ordered, sticky);
12533        } else {
12534            receiver.performReceive(intent, resultCode, data, extras, ordered, sticky);
12535        }
12536    }
12537
12538    private final void deliverToRegisteredReceiver(BroadcastRecord r,
12539            BroadcastFilter filter, boolean ordered) {
12540        boolean skip = false;
12541        if (filter.requiredPermission != null) {
12542            int perm = checkComponentPermission(filter.requiredPermission,
12543                    r.callingPid, r.callingUid, -1);
12544            if (perm != PackageManager.PERMISSION_GRANTED) {
12545                Log.w(TAG, "Permission Denial: broadcasting "
12546                        + r.intent.toString()
12547                        + " from " + r.callerPackage + " (pid="
12548                        + r.callingPid + ", uid=" + r.callingUid + ")"
12549                        + " requires " + filter.requiredPermission
12550                        + " due to registered receiver " + filter);
12551                skip = true;
12552            }
12553        }
12554        if (r.requiredPermission != null) {
12555            int perm = checkComponentPermission(r.requiredPermission,
12556                    filter.receiverList.pid, filter.receiverList.uid, -1);
12557            if (perm != PackageManager.PERMISSION_GRANTED) {
12558                Log.w(TAG, "Permission Denial: receiving "
12559                        + r.intent.toString()
12560                        + " to " + filter.receiverList.app
12561                        + " (pid=" + filter.receiverList.pid
12562                        + ", uid=" + filter.receiverList.uid + ")"
12563                        + " requires " + r.requiredPermission
12564                        + " due to sender " + r.callerPackage
12565                        + " (uid " + r.callingUid + ")");
12566                skip = true;
12567            }
12568        }
12569
12570        if (!skip) {
12571            // If this is not being sent as an ordered broadcast, then we
12572            // don't want to touch the fields that keep track of the current
12573            // state of ordered broadcasts.
12574            if (ordered) {
12575                r.receiver = filter.receiverList.receiver.asBinder();
12576                r.curFilter = filter;
12577                filter.receiverList.curBroadcast = r;
12578                r.state = BroadcastRecord.CALL_IN_RECEIVE;
12579                if (filter.receiverList.app != null) {
12580                    // Bump hosting application to no longer be in background
12581                    // scheduling class.  Note that we can't do that if there
12582                    // isn't an app...  but we can only be in that case for
12583                    // things that directly call the IActivityManager API, which
12584                    // are already core system stuff so don't matter for this.
12585                    r.curApp = filter.receiverList.app;
12586                    filter.receiverList.app.curReceiver = r;
12587                    updateOomAdjLocked();
12588                }
12589            }
12590            try {
12591                if (DEBUG_BROADCAST_LIGHT) {
12592                    int seq = r.intent.getIntExtra("seq", -1);
12593                    Log.i(TAG, "Delivering to " + filter.receiverList.app
12594                            + " (seq=" + seq + "): " + r);
12595                }
12596                performReceive(filter.receiverList.app, filter.receiverList.receiver,
12597                    new Intent(r.intent), r.resultCode,
12598                    r.resultData, r.resultExtras, r.ordered, r.initialSticky);
12599                if (ordered) {
12600                    r.state = BroadcastRecord.CALL_DONE_RECEIVE;
12601                }
12602            } catch (RemoteException e) {
12603                Log.w(TAG, "Failure sending broadcast " + r.intent, e);
12604                if (ordered) {
12605                    r.receiver = null;
12606                    r.curFilter = null;
12607                    filter.receiverList.curBroadcast = null;
12608                    if (filter.receiverList.app != null) {
12609                        filter.receiverList.app.curReceiver = null;
12610                    }
12611                }
12612            }
12613        }
12614    }
12615
12616    private final void addBroadcastToHistoryLocked(BroadcastRecord r) {
12617        if (r.callingUid < 0) {
12618            // This was from a registerReceiver() call; ignore it.
12619            return;
12620        }
12621        System.arraycopy(mBroadcastHistory, 0, mBroadcastHistory, 1,
12622                MAX_BROADCAST_HISTORY-1);
12623        r.finishTime = SystemClock.uptimeMillis();
12624        mBroadcastHistory[0] = r;
12625    }
12626
12627    private final void processNextBroadcast(boolean fromMsg) {
12628        synchronized(this) {
12629            BroadcastRecord r;
12630
12631            if (DEBUG_BROADCAST) Log.v(TAG, "processNextBroadcast: "
12632                    + mParallelBroadcasts.size() + " broadcasts, "
12633                    + mOrderedBroadcasts.size() + " serialized broadcasts");
12634
12635            updateCpuStats();
12636
12637            if (fromMsg) {
12638                mBroadcastsScheduled = false;
12639            }
12640
12641            // First, deliver any non-serialized broadcasts right away.
12642            while (mParallelBroadcasts.size() > 0) {
12643                r = mParallelBroadcasts.remove(0);
12644                r.dispatchTime = SystemClock.uptimeMillis();
12645                final int N = r.receivers.size();
12646                if (DEBUG_BROADCAST_LIGHT) Log.v(TAG, "Processing parallel broadcast "
12647                        + r);
12648                for (int i=0; i<N; i++) {
12649                    Object target = r.receivers.get(i);
12650                    if (DEBUG_BROADCAST)  Log.v(TAG,
12651                            "Delivering non-serialized to registered "
12652                            + target + ": " + r);
12653                    deliverToRegisteredReceiver(r, (BroadcastFilter)target, false);
12654                }
12655                addBroadcastToHistoryLocked(r);
12656                if (DEBUG_BROADCAST_LIGHT) Log.v(TAG, "Done with parallel broadcast "
12657                        + r);
12658            }
12659
12660            // Now take care of the next serialized one...
12661
12662            // If we are waiting for a process to come up to handle the next
12663            // broadcast, then do nothing at this point.  Just in case, we
12664            // check that the process we're waiting for still exists.
12665            if (mPendingBroadcast != null) {
12666                if (DEBUG_BROADCAST_LIGHT) {
12667                    Log.v(TAG, "processNextBroadcast: waiting for "
12668                            + mPendingBroadcast.curApp);
12669                }
12670
12671                boolean isDead;
12672                synchronized (mPidsSelfLocked) {
12673                    isDead = (mPidsSelfLocked.get(mPendingBroadcast.curApp.pid) == null);
12674                }
12675                if (!isDead) {
12676                    // It's still alive, so keep waiting
12677                    return;
12678                } else {
12679                    Log.w(TAG, "pending app " + mPendingBroadcast.curApp
12680                            + " died before responding to broadcast");
12681                    mPendingBroadcast = null;
12682                }
12683            }
12684
12685            boolean looped = false;
12686
12687            do {
12688                if (mOrderedBroadcasts.size() == 0) {
12689                    // No more broadcasts pending, so all done!
12690                    scheduleAppGcsLocked();
12691                    if (looped) {
12692                        // If we had finished the last ordered broadcast, then
12693                        // make sure all processes have correct oom and sched
12694                        // adjustments.
12695                        updateOomAdjLocked();
12696                    }
12697                    return;
12698                }
12699                r = mOrderedBroadcasts.get(0);
12700                boolean forceReceive = false;
12701
12702                // Ensure that even if something goes awry with the timeout
12703                // detection, we catch "hung" broadcasts here, discard them,
12704                // and continue to make progress.
12705                int numReceivers = (r.receivers != null) ? r.receivers.size() : 0;
12706                long now = SystemClock.uptimeMillis();
12707                if (r.dispatchTime > 0) {
12708                    if ((numReceivers > 0) &&
12709                            (now > r.dispatchTime + (2*BROADCAST_TIMEOUT*numReceivers))) {
12710                        Log.w(TAG, "Hung broadcast discarded after timeout failure:"
12711                                + " now=" + now
12712                                + " dispatchTime=" + r.dispatchTime
12713                                + " startTime=" + r.receiverTime
12714                                + " intent=" + r.intent
12715                                + " numReceivers=" + numReceivers
12716                                + " nextReceiver=" + r.nextReceiver
12717                                + " state=" + r.state);
12718                        broadcastTimeout(); // forcibly finish this broadcast
12719                        forceReceive = true;
12720                        r.state = BroadcastRecord.IDLE;
12721                    }
12722                }
12723
12724                if (r.state != BroadcastRecord.IDLE) {
12725                    if (DEBUG_BROADCAST) Log.d(TAG,
12726                            "processNextBroadcast() called when not idle (state="
12727                            + r.state + ")");
12728                    return;
12729                }
12730
12731                if (r.receivers == null || r.nextReceiver >= numReceivers
12732                        || r.resultAbort || forceReceive) {
12733                    // No more receivers for this broadcast!  Send the final
12734                    // result if requested...
12735                    if (r.resultTo != null) {
12736                        try {
12737                            if (DEBUG_BROADCAST) {
12738                                int seq = r.intent.getIntExtra("seq", -1);
12739                                Log.i(TAG, "Finishing broadcast " + r.intent.getAction()
12740                                        + " seq=" + seq + " app=" + r.callerApp);
12741                            }
12742                            performReceive(r.callerApp, r.resultTo,
12743                                new Intent(r.intent), r.resultCode,
12744                                r.resultData, r.resultExtras, false, false);
12745                        } catch (RemoteException e) {
12746                            Log.w(TAG, "Failure sending broadcast result of " + r.intent, e);
12747                        }
12748                    }
12749
12750                    if (DEBUG_BROADCAST) Log.v(TAG, "Cancelling BROADCAST_TIMEOUT_MSG");
12751                    mHandler.removeMessages(BROADCAST_TIMEOUT_MSG);
12752
12753                    if (DEBUG_BROADCAST_LIGHT) Log.v(TAG, "Finished with ordered broadcast "
12754                            + r);
12755
12756                    // ... and on to the next...
12757                    addBroadcastToHistoryLocked(r);
12758                    mOrderedBroadcasts.remove(0);
12759                    r = null;
12760                    looped = true;
12761                    continue;
12762                }
12763            } while (r == null);
12764
12765            // Get the next receiver...
12766            int recIdx = r.nextReceiver++;
12767
12768            // Keep track of when this receiver started, and make sure there
12769            // is a timeout message pending to kill it if need be.
12770            r.receiverTime = SystemClock.uptimeMillis();
12771            if (recIdx == 0) {
12772                r.dispatchTime = r.receiverTime;
12773
12774                if (DEBUG_BROADCAST_LIGHT) Log.v(TAG, "Processing ordered broadcast "
12775                        + r);
12776                if (DEBUG_BROADCAST) Log.v(TAG,
12777                        "Submitting BROADCAST_TIMEOUT_MSG for "
12778                        + (r.receiverTime + BROADCAST_TIMEOUT));
12779                Message msg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG);
12780                mHandler.sendMessageAtTime(msg, r.receiverTime+BROADCAST_TIMEOUT);
12781            }
12782
12783            Object nextReceiver = r.receivers.get(recIdx);
12784            if (nextReceiver instanceof BroadcastFilter) {
12785                // Simple case: this is a registered receiver who gets
12786                // a direct call.
12787                BroadcastFilter filter = (BroadcastFilter)nextReceiver;
12788                if (DEBUG_BROADCAST)  Log.v(TAG,
12789                        "Delivering serialized to registered "
12790                        + filter + ": " + r);
12791                deliverToRegisteredReceiver(r, filter, r.ordered);
12792                if (r.receiver == null || !r.ordered) {
12793                    // The receiver has already finished, so schedule to
12794                    // process the next one.
12795                    r.state = BroadcastRecord.IDLE;
12796                    scheduleBroadcastsLocked();
12797                }
12798                return;
12799            }
12800
12801            // Hard case: need to instantiate the receiver, possibly
12802            // starting its application process to host it.
12803
12804            ResolveInfo info =
12805                (ResolveInfo)nextReceiver;
12806
12807            boolean skip = false;
12808            int perm = checkComponentPermission(info.activityInfo.permission,
12809                    r.callingPid, r.callingUid,
12810                    info.activityInfo.exported
12811                            ? -1 : info.activityInfo.applicationInfo.uid);
12812            if (perm != PackageManager.PERMISSION_GRANTED) {
12813                Log.w(TAG, "Permission Denial: broadcasting "
12814                        + r.intent.toString()
12815                        + " from " + r.callerPackage + " (pid=" + r.callingPid
12816                        + ", uid=" + r.callingUid + ")"
12817                        + " requires " + info.activityInfo.permission
12818                        + " due to receiver " + info.activityInfo.packageName
12819                        + "/" + info.activityInfo.name);
12820                skip = true;
12821            }
12822            if (r.callingUid != Process.SYSTEM_UID &&
12823                r.requiredPermission != null) {
12824                try {
12825                    perm = ActivityThread.getPackageManager().
12826                            checkPermission(r.requiredPermission,
12827                                    info.activityInfo.applicationInfo.packageName);
12828                } catch (RemoteException e) {
12829                    perm = PackageManager.PERMISSION_DENIED;
12830                }
12831                if (perm != PackageManager.PERMISSION_GRANTED) {
12832                    Log.w(TAG, "Permission Denial: receiving "
12833                            + r.intent + " to "
12834                            + info.activityInfo.applicationInfo.packageName
12835                            + " requires " + r.requiredPermission
12836                            + " due to sender " + r.callerPackage
12837                            + " (uid " + r.callingUid + ")");
12838                    skip = true;
12839                }
12840            }
12841            if (r.curApp != null && r.curApp.crashing) {
12842                // If the target process is crashing, just skip it.
12843                skip = true;
12844            }
12845
12846            if (skip) {
12847                r.receiver = null;
12848                r.curFilter = null;
12849                r.state = BroadcastRecord.IDLE;
12850                scheduleBroadcastsLocked();
12851                return;
12852            }
12853
12854            r.state = BroadcastRecord.APP_RECEIVE;
12855            String targetProcess = info.activityInfo.processName;
12856            r.curComponent = new ComponentName(
12857                    info.activityInfo.applicationInfo.packageName,
12858                    info.activityInfo.name);
12859            r.curReceiver = info.activityInfo;
12860
12861            // Is this receiver's application already running?
12862            ProcessRecord app = getProcessRecordLocked(targetProcess,
12863                    info.activityInfo.applicationInfo.uid);
12864            if (app != null && app.thread != null) {
12865                try {
12866                    processCurBroadcastLocked(r, app);
12867                    return;
12868                } catch (RemoteException e) {
12869                    Log.w(TAG, "Exception when sending broadcast to "
12870                          + r.curComponent, e);
12871                }
12872
12873                // If a dead object exception was thrown -- fall through to
12874                // restart the application.
12875            }
12876
12877            // Not running -- get it started, to be executed when the app comes up.
12878            if ((r.curApp=startProcessLocked(targetProcess,
12879                    info.activityInfo.applicationInfo, true,
12880                    r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND,
12881                    "broadcast", r.curComponent,
12882                    (r.intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0))
12883                            == null) {
12884                // Ah, this recipient is unavailable.  Finish it if necessary,
12885                // and mark the broadcast record as ready for the next.
12886                Log.w(TAG, "Unable to launch app "
12887                        + info.activityInfo.applicationInfo.packageName + "/"
12888                        + info.activityInfo.applicationInfo.uid + " for broadcast "
12889                        + r.intent + ": process is bad");
12890                logBroadcastReceiverDiscard(r);
12891                finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
12892                        r.resultExtras, r.resultAbort, true);
12893                scheduleBroadcastsLocked();
12894                r.state = BroadcastRecord.IDLE;
12895                return;
12896            }
12897
12898            mPendingBroadcast = r;
12899        }
12900    }
12901
12902    // =========================================================
12903    // INSTRUMENTATION
12904    // =========================================================
12905
12906    public boolean startInstrumentation(ComponentName className,
12907            String profileFile, int flags, Bundle arguments,
12908            IInstrumentationWatcher watcher) {
12909        // Refuse possible leaked file descriptors
12910        if (arguments != null && arguments.hasFileDescriptors()) {
12911            throw new IllegalArgumentException("File descriptors passed in Bundle");
12912        }
12913
12914        synchronized(this) {
12915            InstrumentationInfo ii = null;
12916            ApplicationInfo ai = null;
12917            try {
12918                ii = mContext.getPackageManager().getInstrumentationInfo(
12919                    className, STOCK_PM_FLAGS);
12920                ai = mContext.getPackageManager().getApplicationInfo(
12921                    ii.targetPackage, STOCK_PM_FLAGS);
12922            } catch (PackageManager.NameNotFoundException e) {
12923            }
12924            if (ii == null) {
12925                reportStartInstrumentationFailure(watcher, className,
12926                        "Unable to find instrumentation info for: " + className);
12927                return false;
12928            }
12929            if (ai == null) {
12930                reportStartInstrumentationFailure(watcher, className,
12931                        "Unable to find instrumentation target package: " + ii.targetPackage);
12932                return false;
12933            }
12934
12935            int match = mContext.getPackageManager().checkSignatures(
12936                    ii.targetPackage, ii.packageName);
12937            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
12938                String msg = "Permission Denial: starting instrumentation "
12939                        + className + " from pid="
12940                        + Binder.getCallingPid()
12941                        + ", uid=" + Binder.getCallingPid()
12942                        + " not allowed because package " + ii.packageName
12943                        + " does not have a signature matching the target "
12944                        + ii.targetPackage;
12945                reportStartInstrumentationFailure(watcher, className, msg);
12946                throw new SecurityException(msg);
12947            }
12948
12949            final long origId = Binder.clearCallingIdentity();
12950            forceStopPackageLocked(ii.targetPackage, -1, true, false);
12951            ProcessRecord app = addAppLocked(ai);
12952            app.instrumentationClass = className;
12953            app.instrumentationInfo = ai;
12954            app.instrumentationProfileFile = profileFile;
12955            app.instrumentationArguments = arguments;
12956            app.instrumentationWatcher = watcher;
12957            app.instrumentationResultClass = className;
12958            Binder.restoreCallingIdentity(origId);
12959        }
12960
12961        return true;
12962    }
12963
12964    /**
12965     * Report errors that occur while attempting to start Instrumentation.  Always writes the
12966     * error to the logs, but if somebody is watching, send the report there too.  This enables
12967     * the "am" command to report errors with more information.
12968     *
12969     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
12970     * @param cn The component name of the instrumentation.
12971     * @param report The error report.
12972     */
12973    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
12974            ComponentName cn, String report) {
12975        Log.w(TAG, report);
12976        try {
12977            if (watcher != null) {
12978                Bundle results = new Bundle();
12979                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
12980                results.putString("Error", report);
12981                watcher.instrumentationStatus(cn, -1, results);
12982            }
12983        } catch (RemoteException e) {
12984            Log.w(TAG, e);
12985        }
12986    }
12987
12988    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
12989        if (app.instrumentationWatcher != null) {
12990            try {
12991                // NOTE:  IInstrumentationWatcher *must* be oneway here
12992                app.instrumentationWatcher.instrumentationFinished(
12993                    app.instrumentationClass,
12994                    resultCode,
12995                    results);
12996            } catch (RemoteException e) {
12997            }
12998        }
12999        app.instrumentationWatcher = null;
13000        app.instrumentationClass = null;
13001        app.instrumentationInfo = null;
13002        app.instrumentationProfileFile = null;
13003        app.instrumentationArguments = null;
13004
13005        forceStopPackageLocked(app.processName, -1, false, false);
13006    }
13007
13008    public void finishInstrumentation(IApplicationThread target,
13009            int resultCode, Bundle results) {
13010        // Refuse possible leaked file descriptors
13011        if (results != null && results.hasFileDescriptors()) {
13012            throw new IllegalArgumentException("File descriptors passed in Intent");
13013        }
13014
13015        synchronized(this) {
13016            ProcessRecord app = getRecordForAppLocked(target);
13017            if (app == null) {
13018                Log.w(TAG, "finishInstrumentation: no app for " + target);
13019                return;
13020            }
13021            final long origId = Binder.clearCallingIdentity();
13022            finishInstrumentationLocked(app, resultCode, results);
13023            Binder.restoreCallingIdentity(origId);
13024        }
13025    }
13026
13027    // =========================================================
13028    // CONFIGURATION
13029    // =========================================================
13030
13031    public ConfigurationInfo getDeviceConfigurationInfo() {
13032        ConfigurationInfo config = new ConfigurationInfo();
13033        synchronized (this) {
13034            config.reqTouchScreen = mConfiguration.touchscreen;
13035            config.reqKeyboardType = mConfiguration.keyboard;
13036            config.reqNavigation = mConfiguration.navigation;
13037            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
13038                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
13039                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
13040            }
13041            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
13042                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
13043                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
13044            }
13045            config.reqGlEsVersion = GL_ES_VERSION;
13046        }
13047        return config;
13048    }
13049
13050    public Configuration getConfiguration() {
13051        Configuration ci;
13052        synchronized(this) {
13053            ci = new Configuration(mConfiguration);
13054        }
13055        return ci;
13056    }
13057
13058    public void updateConfiguration(Configuration values) {
13059        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
13060                "updateConfiguration()");
13061
13062        synchronized(this) {
13063            if (values == null && mWindowManager != null) {
13064                // sentinel: fetch the current configuration from the window manager
13065                values = mWindowManager.computeNewConfiguration();
13066            }
13067
13068            final long origId = Binder.clearCallingIdentity();
13069            updateConfigurationLocked(values, null);
13070            Binder.restoreCallingIdentity(origId);
13071        }
13072    }
13073
13074    /**
13075     * Do either or both things: (1) change the current configuration, and (2)
13076     * make sure the given activity is running with the (now) current
13077     * configuration.  Returns true if the activity has been left running, or
13078     * false if <var>starting</var> is being destroyed to match the new
13079     * configuration.
13080     */
13081    public boolean updateConfigurationLocked(Configuration values,
13082            HistoryRecord starting) {
13083        int changes = 0;
13084
13085        boolean kept = true;
13086
13087        if (values != null) {
13088            Configuration newConfig = new Configuration(mConfiguration);
13089            changes = newConfig.updateFrom(values);
13090            if (changes != 0) {
13091                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
13092                    Log.i(TAG, "Updating configuration to: " + values);
13093                }
13094
13095                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
13096
13097                if (values.locale != null) {
13098                    saveLocaleLocked(values.locale,
13099                                     !values.locale.equals(mConfiguration.locale),
13100                                     values.userSetLocale);
13101                }
13102
13103                mConfiguration = newConfig;
13104                Log.i(TAG, "Config changed: " + newConfig);
13105
13106                AttributeCache ac = AttributeCache.instance();
13107                if (ac != null) {
13108                    ac.updateConfiguration(mConfiguration);
13109                }
13110
13111                Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
13112                msg.obj = new Configuration(mConfiguration);
13113                mHandler.sendMessage(msg);
13114
13115                for (int i=mLruProcesses.size()-1; i>=0; i--) {
13116                    ProcessRecord app = mLruProcesses.get(i);
13117                    try {
13118                        if (app.thread != null) {
13119                            if (DEBUG_CONFIGURATION) Log.v(TAG, "Sending to proc "
13120                                    + app.processName + " new config " + mConfiguration);
13121                            app.thread.scheduleConfigurationChanged(mConfiguration);
13122                        }
13123                    } catch (Exception e) {
13124                    }
13125                }
13126                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
13127                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
13128                        | Intent.FLAG_RECEIVER_REPLACE_PENDING);
13129                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
13130                        null, false, false, MY_PID, Process.SYSTEM_UID);
13131                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
13132                    broadcastIntentLocked(null, null,
13133                            new Intent(Intent.ACTION_LOCALE_CHANGED),
13134                            null, null, 0, null, null,
13135                            null, false, false, MY_PID, Process.SYSTEM_UID);
13136                }
13137            }
13138        }
13139
13140        if (changes != 0 && starting == null) {
13141            // If the configuration changed, and the caller is not already
13142            // in the process of starting an activity, then find the top
13143            // activity to check if its configuration needs to change.
13144            starting = topRunningActivityLocked(null);
13145        }
13146
13147        if (starting != null) {
13148            kept = ensureActivityConfigurationLocked(starting, changes);
13149            if (kept) {
13150                // If this didn't result in the starting activity being
13151                // destroyed, then we need to make sure at this point that all
13152                // other activities are made visible.
13153                if (DEBUG_SWITCH) Log.i(TAG, "Config didn't destroy " + starting
13154                        + ", ensuring others are correct.");
13155                ensureActivitiesVisibleLocked(starting, changes);
13156            }
13157        }
13158
13159        return kept;
13160    }
13161
13162    private final boolean relaunchActivityLocked(HistoryRecord r,
13163            int changes, boolean andResume) {
13164        List<ResultInfo> results = null;
13165        List<Intent> newIntents = null;
13166        if (andResume) {
13167            results = r.results;
13168            newIntents = r.newIntents;
13169        }
13170        if (DEBUG_SWITCH) Log.v(TAG, "Relaunching: " + r
13171                + " with results=" + results + " newIntents=" + newIntents
13172                + " andResume=" + andResume);
13173        EventLog.writeEvent(andResume ? EventLogTags.AM_RELAUNCH_RESUME_ACTIVITY
13174                : EventLogTags.AM_RELAUNCH_ACTIVITY, System.identityHashCode(r),
13175                r.task.taskId, r.shortComponentName);
13176
13177        r.startFreezingScreenLocked(r.app, 0);
13178
13179        try {
13180            if (DEBUG_SWITCH) Log.i(TAG, "Switch is restarting resumed " + r);
13181            r.app.thread.scheduleRelaunchActivity(r, results, newIntents,
13182                    changes, !andResume, mConfiguration);
13183            // Note: don't need to call pauseIfSleepingLocked() here, because
13184            // the caller will only pass in 'andResume' if this activity is
13185            // currently resumed, which implies we aren't sleeping.
13186        } catch (RemoteException e) {
13187            return false;
13188        }
13189
13190        if (andResume) {
13191            r.results = null;
13192            r.newIntents = null;
13193            reportResumedActivityLocked(r);
13194        }
13195
13196        return true;
13197    }
13198
13199    /**
13200     * Make sure the given activity matches the current configuration.  Returns
13201     * false if the activity had to be destroyed.  Returns true if the
13202     * configuration is the same, or the activity will remain running as-is
13203     * for whatever reason.  Ensures the HistoryRecord is updated with the
13204     * correct configuration and all other bookkeeping is handled.
13205     */
13206    private final boolean ensureActivityConfigurationLocked(HistoryRecord r,
13207            int globalChanges) {
13208        if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Log.v(TAG,
13209                "Ensuring correct configuration: " + r);
13210
13211        // Short circuit: if the two configurations are the exact same
13212        // object (the common case), then there is nothing to do.
13213        Configuration newConfig = mConfiguration;
13214        if (r.configuration == newConfig) {
13215            if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Log.v(TAG,
13216                    "Configuration unchanged in " + r);
13217            return true;
13218        }
13219
13220        // We don't worry about activities that are finishing.
13221        if (r.finishing) {
13222            if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Log.v(TAG,
13223                    "Configuration doesn't matter in finishing " + r);
13224            r.stopFreezingScreenLocked(false);
13225            return true;
13226        }
13227
13228        // Okay we now are going to make this activity have the new config.
13229        // But then we need to figure out how it needs to deal with that.
13230        Configuration oldConfig = r.configuration;
13231        r.configuration = newConfig;
13232
13233        // If the activity isn't currently running, just leave the new
13234        // configuration and it will pick that up next time it starts.
13235        if (r.app == null || r.app.thread == null) {
13236            if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Log.v(TAG,
13237                    "Configuration doesn't matter not running " + r);
13238            r.stopFreezingScreenLocked(false);
13239            return true;
13240        }
13241
13242        // If the activity isn't persistent, there is a chance we will
13243        // need to restart it.
13244        if (!r.persistent) {
13245
13246            // Figure out what has changed between the two configurations.
13247            int changes = oldConfig.diff(newConfig);
13248            if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
13249                Log.v(TAG, "Checking to restart " + r.info.name + ": changed=0x"
13250                        + Integer.toHexString(changes) + ", handles=0x"
13251                        + Integer.toHexString(r.info.configChanges)
13252                        + ", newConfig=" + newConfig);
13253            }
13254            if ((changes&(~r.info.configChanges)) != 0) {
13255                // Aha, the activity isn't handling the change, so DIE DIE DIE.
13256                r.configChangeFlags |= changes;
13257                r.startFreezingScreenLocked(r.app, globalChanges);
13258                if (r.app == null || r.app.thread == null) {
13259                    if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Log.v(TAG,
13260                            "Switch is destroying non-running " + r);
13261                    destroyActivityLocked(r, true);
13262                } else if (r.state == ActivityState.PAUSING) {
13263                    // A little annoying: we are waiting for this activity to
13264                    // finish pausing.  Let's not do anything now, but just
13265                    // flag that it needs to be restarted when done pausing.
13266                    if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Log.v(TAG,
13267                            "Switch is skipping already pausing " + r);
13268                    r.configDestroy = true;
13269                    return true;
13270                } else if (r.state == ActivityState.RESUMED) {
13271                    // Try to optimize this case: the configuration is changing
13272                    // and we need to restart the top, resumed activity.
13273                    // Instead of doing the normal handshaking, just say
13274                    // "restart!".
13275                    if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Log.v(TAG,
13276                            "Switch is restarting resumed " + r);
13277                    relaunchActivityLocked(r, r.configChangeFlags, true);
13278                    r.configChangeFlags = 0;
13279                } else {
13280                    if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Log.v(TAG,
13281                            "Switch is restarting non-resumed " + r);
13282                    relaunchActivityLocked(r, r.configChangeFlags, false);
13283                    r.configChangeFlags = 0;
13284                }
13285
13286                // All done...  tell the caller we weren't able to keep this
13287                // activity around.
13288                return false;
13289            }
13290        }
13291
13292        // Default case: the activity can handle this new configuration, so
13293        // hand it over.  Note that we don't need to give it the new
13294        // configuration, since we always send configuration changes to all
13295        // process when they happen so it can just use whatever configuration
13296        // it last got.
13297        if (r.app != null && r.app.thread != null) {
13298            try {
13299                if (DEBUG_CONFIGURATION) Log.v(TAG, "Sending new config to " + r);
13300                r.app.thread.scheduleActivityConfigurationChanged(r);
13301            } catch (RemoteException e) {
13302                // If process died, whatever.
13303            }
13304        }
13305        r.stopFreezingScreenLocked(false);
13306
13307        return true;
13308    }
13309
13310    /**
13311     * Save the locale.  You must be inside a synchronized (this) block.
13312     */
13313    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
13314        if(isDiff) {
13315            SystemProperties.set("user.language", l.getLanguage());
13316            SystemProperties.set("user.region", l.getCountry());
13317        }
13318
13319        if(isPersist) {
13320            SystemProperties.set("persist.sys.language", l.getLanguage());
13321            SystemProperties.set("persist.sys.country", l.getCountry());
13322            SystemProperties.set("persist.sys.localevar", l.getVariant());
13323        }
13324    }
13325
13326    // =========================================================
13327    // LIFETIME MANAGEMENT
13328    // =========================================================
13329
13330    private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj,
13331            ProcessRecord TOP_APP, boolean recursed) {
13332        if (mAdjSeq == app.adjSeq) {
13333            // This adjustment has already been computed.  If we are calling
13334            // from the top, we may have already computed our adjustment with
13335            // an earlier hidden adjustment that isn't really for us... if
13336            // so, use the new hidden adjustment.
13337            if (!recursed && app.hidden) {
13338                app.curAdj = hiddenAdj;
13339            }
13340            return app.curAdj;
13341        }
13342
13343        if (app.thread == null) {
13344            app.adjSeq = mAdjSeq;
13345            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
13346            return (app.curAdj=EMPTY_APP_ADJ);
13347        }
13348
13349        if (app.maxAdj <= FOREGROUND_APP_ADJ) {
13350            // The max adjustment doesn't allow this app to be anything
13351            // below foreground, so it is not worth doing work for it.
13352            app.adjType = "fixed";
13353            app.adjSeq = mAdjSeq;
13354            app.curRawAdj = app.maxAdj;
13355            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
13356            return (app.curAdj=app.maxAdj);
13357       }
13358
13359        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
13360        app.adjSource = null;
13361        app.adjTarget = null;
13362        app.empty = false;
13363        app.hidden = false;
13364
13365        // Determine the importance of the process, starting with most
13366        // important to least, and assign an appropriate OOM adjustment.
13367        int adj;
13368        int schedGroup;
13369        int N;
13370        if (app == TOP_APP) {
13371            // The last app on the list is the foreground app.
13372            adj = FOREGROUND_APP_ADJ;
13373            schedGroup = Process.THREAD_GROUP_DEFAULT;
13374            app.adjType = "top-activity";
13375        } else if (app.instrumentationClass != null) {
13376            // Don't want to kill running instrumentation.
13377            adj = FOREGROUND_APP_ADJ;
13378            schedGroup = Process.THREAD_GROUP_DEFAULT;
13379            app.adjType = "instrumentation";
13380        } else if (app.persistentActivities > 0) {
13381            // Special persistent activities...  shouldn't be used these days.
13382            adj = FOREGROUND_APP_ADJ;
13383            schedGroup = Process.THREAD_GROUP_DEFAULT;
13384            app.adjType = "persistent";
13385        } else if (app.curReceiver != null ||
13386                (mPendingBroadcast != null && mPendingBroadcast.curApp == app)) {
13387            // An app that is currently receiving a broadcast also
13388            // counts as being in the foreground.
13389            adj = FOREGROUND_APP_ADJ;
13390            schedGroup = Process.THREAD_GROUP_DEFAULT;
13391            app.adjType = "broadcast";
13392        } else if (app.executingServices.size() > 0) {
13393            // An app that is currently executing a service callback also
13394            // counts as being in the foreground.
13395            adj = FOREGROUND_APP_ADJ;
13396            schedGroup = Process.THREAD_GROUP_DEFAULT;
13397            app.adjType = "exec-service";
13398        } else if (app.foregroundServices) {
13399            // The user is aware of this app, so make it visible.
13400            adj = VISIBLE_APP_ADJ;
13401            schedGroup = Process.THREAD_GROUP_DEFAULT;
13402            app.adjType = "foreground-service";
13403        } else if (app.forcingToForeground != null) {
13404            // The user is aware of this app, so make it visible.
13405            adj = VISIBLE_APP_ADJ;
13406            schedGroup = Process.THREAD_GROUP_DEFAULT;
13407            app.adjType = "force-foreground";
13408            app.adjSource = app.forcingToForeground;
13409        } else if (app == mHomeProcess) {
13410            // This process is hosting what we currently consider to be the
13411            // home app, so we don't want to let it go into the background.
13412            adj = HOME_APP_ADJ;
13413            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
13414            app.adjType = "home";
13415        } else if ((N=app.activities.size()) != 0) {
13416            // This app is in the background with paused activities.
13417            app.hidden = true;
13418            adj = hiddenAdj;
13419            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
13420            app.adjType = "bg-activities";
13421            N = app.activities.size();
13422            for (int j=0; j<N; j++) {
13423                if (((HistoryRecord)app.activities.get(j)).visible) {
13424                    // This app has a visible activity!
13425                    app.hidden = false;
13426                    adj = VISIBLE_APP_ADJ;
13427                    schedGroup = Process.THREAD_GROUP_DEFAULT;
13428                    app.adjType = "visible";
13429                    break;
13430                }
13431            }
13432        } else {
13433            // A very not-needed process.  If this is lower in the lru list,
13434            // we will push it in to the empty bucket.
13435            app.hidden = true;
13436            app.empty = true;
13437            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
13438            adj = hiddenAdj;
13439            app.adjType = "bg-empty";
13440        }
13441
13442        //Log.i(TAG, "OOM " + app + ": initial adj=" + adj);
13443
13444        // By default, we use the computed adjustment.  It may be changed if
13445        // there are applications dependent on our services or providers, but
13446        // this gives us a baseline and makes sure we don't get into an
13447        // infinite recursion.
13448        app.adjSeq = mAdjSeq;
13449        app.curRawAdj = adj;
13450
13451        if (mBackupTarget != null && app == mBackupTarget.app) {
13452            // If possible we want to avoid killing apps while they're being backed up
13453            if (adj > BACKUP_APP_ADJ) {
13454                if (DEBUG_BACKUP) Log.v(TAG, "oom BACKUP_APP_ADJ for " + app);
13455                adj = BACKUP_APP_ADJ;
13456                app.adjType = "backup";
13457                app.hidden = false;
13458            }
13459        }
13460
13461        if (app.services.size() != 0 && (adj > FOREGROUND_APP_ADJ
13462                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
13463            final long now = SystemClock.uptimeMillis();
13464            // This process is more important if the top activity is
13465            // bound to the service.
13466            Iterator jt = app.services.iterator();
13467            while (jt.hasNext() && adj > FOREGROUND_APP_ADJ) {
13468                ServiceRecord s = (ServiceRecord)jt.next();
13469                if (s.startRequested) {
13470                    if (now < (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
13471                        // This service has seen some activity within
13472                        // recent memory, so we will keep its process ahead
13473                        // of the background processes.
13474                        if (adj > SECONDARY_SERVER_ADJ) {
13475                            adj = SECONDARY_SERVER_ADJ;
13476                            app.adjType = "started-services";
13477                            app.hidden = false;
13478                        }
13479                    }
13480                }
13481                if (s.connections.size() > 0 && (adj > FOREGROUND_APP_ADJ
13482                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
13483                    Iterator<ConnectionRecord> kt
13484                            = s.connections.values().iterator();
13485                    while (kt.hasNext() && adj > FOREGROUND_APP_ADJ) {
13486                        // XXX should compute this based on the max of
13487                        // all connected clients.
13488                        ConnectionRecord cr = kt.next();
13489                        if (cr.binding.client == app) {
13490                            // Binding to ourself is not interesting.
13491                            continue;
13492                        }
13493                        if ((cr.flags&Context.BIND_AUTO_CREATE) != 0) {
13494                            ProcessRecord client = cr.binding.client;
13495                            int myHiddenAdj = hiddenAdj;
13496                            if (myHiddenAdj > client.hiddenAdj) {
13497                                if (client.hiddenAdj > VISIBLE_APP_ADJ) {
13498                                    myHiddenAdj = client.hiddenAdj;
13499                                } else {
13500                                    myHiddenAdj = VISIBLE_APP_ADJ;
13501                                }
13502                            }
13503                            int clientAdj = computeOomAdjLocked(
13504                                client, myHiddenAdj, TOP_APP, true);
13505                            if (adj > clientAdj) {
13506                                adj = clientAdj > VISIBLE_APP_ADJ
13507                                        ? clientAdj : VISIBLE_APP_ADJ;
13508                                if (!client.hidden) {
13509                                    app.hidden = false;
13510                                }
13511                                app.adjType = "service";
13512                                app.adjTypeCode = ActivityManager.RunningAppProcessInfo
13513                                        .REASON_SERVICE_IN_USE;
13514                                app.adjSource = cr.binding.client;
13515                                app.adjTarget = s.serviceInfo.name;
13516                            }
13517                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
13518                                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
13519                                    schedGroup = Process.THREAD_GROUP_DEFAULT;
13520                                }
13521                            }
13522                        }
13523                        HistoryRecord a = cr.activity;
13524                        //if (a != null) {
13525                        //    Log.i(TAG, "Connection to " + a ": state=" + a.state);
13526                        //}
13527                        if (a != null && adj > FOREGROUND_APP_ADJ &&
13528                                (a.state == ActivityState.RESUMED
13529                                 || a.state == ActivityState.PAUSING)) {
13530                            adj = FOREGROUND_APP_ADJ;
13531                            schedGroup = Process.THREAD_GROUP_DEFAULT;
13532                            app.hidden = false;
13533                            app.adjType = "service";
13534                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
13535                                    .REASON_SERVICE_IN_USE;
13536                            app.adjSource = a;
13537                            app.adjTarget = s.serviceInfo.name;
13538                        }
13539                    }
13540                }
13541            }
13542
13543            // Finally, f this process has active services running in it, we
13544            // would like to avoid killing it unless it would prevent the current
13545            // application from running.  By default we put the process in
13546            // with the rest of the background processes; as we scan through
13547            // its services we may bump it up from there.
13548            if (adj > hiddenAdj) {
13549                adj = hiddenAdj;
13550                app.hidden = false;
13551                app.adjType = "bg-services";
13552            }
13553        }
13554
13555        if (app.pubProviders.size() != 0 && (adj > FOREGROUND_APP_ADJ
13556                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
13557            Iterator jt = app.pubProviders.values().iterator();
13558            while (jt.hasNext() && (adj > FOREGROUND_APP_ADJ
13559                    || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
13560                ContentProviderRecord cpr = (ContentProviderRecord)jt.next();
13561                if (cpr.clients.size() != 0) {
13562                    Iterator<ProcessRecord> kt = cpr.clients.iterator();
13563                    while (kt.hasNext() && adj > FOREGROUND_APP_ADJ) {
13564                        ProcessRecord client = kt.next();
13565                        if (client == app) {
13566                            // Being our own client is not interesting.
13567                            continue;
13568                        }
13569                        int myHiddenAdj = hiddenAdj;
13570                        if (myHiddenAdj > client.hiddenAdj) {
13571                            if (client.hiddenAdj > FOREGROUND_APP_ADJ) {
13572                                myHiddenAdj = client.hiddenAdj;
13573                            } else {
13574                                myHiddenAdj = FOREGROUND_APP_ADJ;
13575                            }
13576                        }
13577                        int clientAdj = computeOomAdjLocked(
13578                            client, myHiddenAdj, TOP_APP, true);
13579                        if (adj > clientAdj) {
13580                            adj = clientAdj > FOREGROUND_APP_ADJ
13581                                    ? clientAdj : FOREGROUND_APP_ADJ;
13582                            if (!client.hidden) {
13583                                app.hidden = false;
13584                            }
13585                            app.adjType = "provider";
13586                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
13587                                    .REASON_PROVIDER_IN_USE;
13588                            app.adjSource = client;
13589                            app.adjTarget = cpr.info.name;
13590                        }
13591                        if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
13592                            schedGroup = Process.THREAD_GROUP_DEFAULT;
13593                        }
13594                    }
13595                }
13596                // If the provider has external (non-framework) process
13597                // dependencies, ensure that its adjustment is at least
13598                // FOREGROUND_APP_ADJ.
13599                if (cpr.externals != 0) {
13600                    if (adj > FOREGROUND_APP_ADJ) {
13601                        adj = FOREGROUND_APP_ADJ;
13602                        schedGroup = Process.THREAD_GROUP_DEFAULT;
13603                        app.hidden = false;
13604                        app.adjType = "provider";
13605                        app.adjTarget = cpr.info.name;
13606                    }
13607                }
13608            }
13609        }
13610
13611        app.curRawAdj = adj;
13612
13613        //Log.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
13614        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
13615        if (adj > app.maxAdj) {
13616            adj = app.maxAdj;
13617            if (app.maxAdj <= VISIBLE_APP_ADJ) {
13618                schedGroup = Process.THREAD_GROUP_DEFAULT;
13619            }
13620        }
13621
13622        app.curAdj = adj;
13623        app.curSchedGroup = schedGroup;
13624
13625        return adj;
13626    }
13627
13628    /**
13629     * Ask a given process to GC right now.
13630     */
13631    final void performAppGcLocked(ProcessRecord app) {
13632        try {
13633            app.lastRequestedGc = SystemClock.uptimeMillis();
13634            if (app.thread != null) {
13635                if (app.reportLowMemory) {
13636                    app.reportLowMemory = false;
13637                    app.thread.scheduleLowMemory();
13638                } else {
13639                    app.thread.processInBackground();
13640                }
13641            }
13642        } catch (Exception e) {
13643            // whatever.
13644        }
13645    }
13646
13647    /**
13648     * Returns true if things are idle enough to perform GCs.
13649     */
13650    private final boolean canGcNow() {
13651        return mParallelBroadcasts.size() == 0
13652                && mOrderedBroadcasts.size() == 0
13653                && (mSleeping || (mResumedActivity != null &&
13654                        mResumedActivity.idle));
13655    }
13656
13657    /**
13658     * Perform GCs on all processes that are waiting for it, but only
13659     * if things are idle.
13660     */
13661    final void performAppGcsLocked() {
13662        final int N = mProcessesToGc.size();
13663        if (N <= 0) {
13664            return;
13665        }
13666        if (canGcNow()) {
13667            while (mProcessesToGc.size() > 0) {
13668                ProcessRecord proc = mProcessesToGc.remove(0);
13669                if (proc.curRawAdj > VISIBLE_APP_ADJ || proc.reportLowMemory) {
13670                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
13671                            <= SystemClock.uptimeMillis()) {
13672                        // To avoid spamming the system, we will GC processes one
13673                        // at a time, waiting a few seconds between each.
13674                        performAppGcLocked(proc);
13675                        scheduleAppGcsLocked();
13676                        return;
13677                    } else {
13678                        // It hasn't been long enough since we last GCed this
13679                        // process...  put it in the list to wait for its time.
13680                        addProcessToGcListLocked(proc);
13681                        break;
13682                    }
13683                }
13684            }
13685
13686            scheduleAppGcsLocked();
13687        }
13688    }
13689
13690    /**
13691     * If all looks good, perform GCs on all processes waiting for them.
13692     */
13693    final void performAppGcsIfAppropriateLocked() {
13694        if (canGcNow()) {
13695            performAppGcsLocked();
13696            return;
13697        }
13698        // Still not idle, wait some more.
13699        scheduleAppGcsLocked();
13700    }
13701
13702    /**
13703     * Schedule the execution of all pending app GCs.
13704     */
13705    final void scheduleAppGcsLocked() {
13706        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
13707
13708        if (mProcessesToGc.size() > 0) {
13709            // Schedule a GC for the time to the next process.
13710            ProcessRecord proc = mProcessesToGc.get(0);
13711            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
13712
13713            long when = mProcessesToGc.get(0).lastRequestedGc + GC_MIN_INTERVAL;
13714            long now = SystemClock.uptimeMillis();
13715            if (when < (now+GC_TIMEOUT)) {
13716                when = now + GC_TIMEOUT;
13717            }
13718            mHandler.sendMessageAtTime(msg, when);
13719        }
13720    }
13721
13722    /**
13723     * Add a process to the array of processes waiting to be GCed.  Keeps the
13724     * list in sorted order by the last GC time.  The process can't already be
13725     * on the list.
13726     */
13727    final void addProcessToGcListLocked(ProcessRecord proc) {
13728        boolean added = false;
13729        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
13730            if (mProcessesToGc.get(i).lastRequestedGc <
13731                    proc.lastRequestedGc) {
13732                added = true;
13733                mProcessesToGc.add(i+1, proc);
13734                break;
13735            }
13736        }
13737        if (!added) {
13738            mProcessesToGc.add(0, proc);
13739        }
13740    }
13741
13742    /**
13743     * Set up to ask a process to GC itself.  This will either do it
13744     * immediately, or put it on the list of processes to gc the next
13745     * time things are idle.
13746     */
13747    final void scheduleAppGcLocked(ProcessRecord app) {
13748        long now = SystemClock.uptimeMillis();
13749        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
13750            return;
13751        }
13752        if (!mProcessesToGc.contains(app)) {
13753            addProcessToGcListLocked(app);
13754            scheduleAppGcsLocked();
13755        }
13756    }
13757
13758    private final boolean updateOomAdjLocked(
13759        ProcessRecord app, int hiddenAdj, ProcessRecord TOP_APP) {
13760        app.hiddenAdj = hiddenAdj;
13761
13762        if (app.thread == null) {
13763            return true;
13764        }
13765
13766        int adj = computeOomAdjLocked(app, hiddenAdj, TOP_APP, false);
13767
13768        if ((app.pid != 0 && app.pid != MY_PID) || Process.supportsProcesses()) {
13769            if (app.curRawAdj != app.setRawAdj) {
13770                if (app.curRawAdj > FOREGROUND_APP_ADJ
13771                        && app.setRawAdj <= FOREGROUND_APP_ADJ) {
13772                    // If this app is transitioning from foreground to
13773                    // non-foreground, have it do a gc.
13774                    scheduleAppGcLocked(app);
13775                } else if (app.curRawAdj >= HIDDEN_APP_MIN_ADJ
13776                        && app.setRawAdj < HIDDEN_APP_MIN_ADJ) {
13777                    // Likewise do a gc when an app is moving in to the
13778                    // background (such as a service stopping).
13779                    scheduleAppGcLocked(app);
13780                }
13781                app.setRawAdj = app.curRawAdj;
13782            }
13783            if (adj != app.setAdj) {
13784                if (Process.setOomAdj(app.pid, adj)) {
13785                    if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Log.v(
13786                        TAG, "Set app " + app.processName +
13787                        " oom adj to " + adj);
13788                    app.setAdj = adj;
13789                } else {
13790                    return false;
13791                }
13792            }
13793            if (app.setSchedGroup != app.curSchedGroup) {
13794                app.setSchedGroup = app.curSchedGroup;
13795                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Log.v(TAG,
13796                        "Setting process group of " + app.processName
13797                        + " to " + app.curSchedGroup);
13798                if (true) {
13799                    long oldId = Binder.clearCallingIdentity();
13800                    try {
13801                        Process.setProcessGroup(app.pid, app.curSchedGroup);
13802                    } catch (Exception e) {
13803                        Log.w(TAG, "Failed setting process group of " + app.pid
13804                                + " to " + app.curSchedGroup);
13805                        e.printStackTrace();
13806                    } finally {
13807                        Binder.restoreCallingIdentity(oldId);
13808                    }
13809                }
13810                if (false) {
13811                    if (app.thread != null) {
13812                        try {
13813                            app.thread.setSchedulingGroup(app.curSchedGroup);
13814                        } catch (RemoteException e) {
13815                        }
13816                    }
13817                }
13818            }
13819        }
13820
13821        return true;
13822    }
13823
13824    private final HistoryRecord resumedAppLocked() {
13825        HistoryRecord resumedActivity = mResumedActivity;
13826        if (resumedActivity == null || resumedActivity.app == null) {
13827            resumedActivity = mPausingActivity;
13828            if (resumedActivity == null || resumedActivity.app == null) {
13829                resumedActivity = topRunningActivityLocked(null);
13830            }
13831        }
13832        return resumedActivity;
13833    }
13834
13835    private final boolean updateOomAdjLocked(ProcessRecord app) {
13836        final HistoryRecord TOP_ACT = resumedAppLocked();
13837        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13838        int curAdj = app.curAdj;
13839        final boolean wasHidden = app.curAdj >= HIDDEN_APP_MIN_ADJ
13840            && app.curAdj <= HIDDEN_APP_MAX_ADJ;
13841
13842        mAdjSeq++;
13843
13844        final boolean res = updateOomAdjLocked(app, app.hiddenAdj, TOP_APP);
13845        if (res) {
13846            final boolean nowHidden = app.curAdj >= HIDDEN_APP_MIN_ADJ
13847                && app.curAdj <= HIDDEN_APP_MAX_ADJ;
13848            if (nowHidden != wasHidden) {
13849                // Changed to/from hidden state, so apps after it in the LRU
13850                // list may also be changed.
13851                updateOomAdjLocked();
13852            }
13853        }
13854        return res;
13855    }
13856
13857    private final boolean updateOomAdjLocked() {
13858        boolean didOomAdj = true;
13859        final HistoryRecord TOP_ACT = resumedAppLocked();
13860        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13861
13862        if (false) {
13863            RuntimeException e = new RuntimeException();
13864            e.fillInStackTrace();
13865            Log.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
13866        }
13867
13868        mAdjSeq++;
13869
13870        // First try updating the OOM adjustment for each of the
13871        // application processes based on their current state.
13872        int i = mLruProcesses.size();
13873        int curHiddenAdj = HIDDEN_APP_MIN_ADJ;
13874        while (i > 0) {
13875            i--;
13876            ProcessRecord app = mLruProcesses.get(i);
13877            //Log.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj);
13878            if (updateOomAdjLocked(app, curHiddenAdj, TOP_APP)) {
13879                if (curHiddenAdj < EMPTY_APP_ADJ
13880                    && app.curAdj == curHiddenAdj) {
13881                    curHiddenAdj++;
13882                }
13883            } else {
13884                didOomAdj = false;
13885            }
13886        }
13887
13888        // If we return false, we will fall back on killing processes to
13889        // have a fixed limit.  Do this if a limit has been requested; else
13890        // only return false if one of the adjustments failed.
13891        return ENFORCE_PROCESS_LIMIT || mProcessLimit > 0 ? false : didOomAdj;
13892    }
13893
13894    private final void trimApplications() {
13895        synchronized (this) {
13896            int i;
13897
13898            // First remove any unused application processes whose package
13899            // has been removed.
13900            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
13901                final ProcessRecord app = mRemovedProcesses.get(i);
13902                if (app.activities.size() == 0
13903                        && app.curReceiver == null && app.services.size() == 0) {
13904                    Log.i(
13905                        TAG, "Exiting empty application process "
13906                        + app.processName + " ("
13907                        + (app.thread != null ? app.thread.asBinder() : null)
13908                        + ")\n");
13909                    if (app.pid > 0 && app.pid != MY_PID) {
13910                        Process.killProcess(app.pid);
13911                    } else {
13912                        try {
13913                            app.thread.scheduleExit();
13914                        } catch (Exception e) {
13915                            // Ignore exceptions.
13916                        }
13917                    }
13918                    cleanUpApplicationRecordLocked(app, false, -1);
13919                    mRemovedProcesses.remove(i);
13920
13921                    if (app.persistent) {
13922                        if (app.persistent) {
13923                            addAppLocked(app.info);
13924                        }
13925                    }
13926                }
13927            }
13928
13929            // Now try updating the OOM adjustment for each of the
13930            // application processes based on their current state.
13931            // If the setOomAdj() API is not supported, then go with our
13932            // back-up plan...
13933            if (!updateOomAdjLocked()) {
13934
13935                // Count how many processes are running services.
13936                int numServiceProcs = 0;
13937                for (i=mLruProcesses.size()-1; i>=0; i--) {
13938                    final ProcessRecord app = mLruProcesses.get(i);
13939
13940                    if (app.persistent || app.services.size() != 0
13941                            || app.curReceiver != null
13942                            || app.persistentActivities > 0) {
13943                        // Don't count processes holding services against our
13944                        // maximum process count.
13945                        if (localLOGV) Log.v(
13946                            TAG, "Not trimming app " + app + " with services: "
13947                            + app.services);
13948                        numServiceProcs++;
13949                    }
13950                }
13951
13952                int curMaxProcs = mProcessLimit;
13953                if (curMaxProcs <= 0) curMaxProcs = MAX_PROCESSES;
13954                if (mAlwaysFinishActivities) {
13955                    curMaxProcs = 1;
13956                }
13957                curMaxProcs += numServiceProcs;
13958
13959                // Quit as many processes as we can to get down to the desired
13960                // process count.  First remove any processes that no longer
13961                // have activites running in them.
13962                for (   i=0;
13963                        i<mLruProcesses.size()
13964                            && mLruProcesses.size() > curMaxProcs;
13965                        i++) {
13966                    final ProcessRecord app = mLruProcesses.get(i);
13967                    // Quit an application only if it is not currently
13968                    // running any activities.
13969                    if (!app.persistent && app.activities.size() == 0
13970                            && app.curReceiver == null && app.services.size() == 0) {
13971                        Log.i(
13972                            TAG, "Exiting empty application process "
13973                            + app.processName + " ("
13974                            + (app.thread != null ? app.thread.asBinder() : null)
13975                            + ")\n");
13976                        if (app.pid > 0 && app.pid != MY_PID) {
13977                            Process.killProcess(app.pid);
13978                        } else {
13979                            try {
13980                                app.thread.scheduleExit();
13981                            } catch (Exception e) {
13982                                // Ignore exceptions.
13983                            }
13984                        }
13985                        // todo: For now we assume the application is not buggy
13986                        // or evil, and will quit as a result of our request.
13987                        // Eventually we need to drive this off of the death
13988                        // notification, and kill the process if it takes too long.
13989                        cleanUpApplicationRecordLocked(app, false, i);
13990                        i--;
13991                    }
13992                }
13993
13994                // If we still have too many processes, now from the least
13995                // recently used process we start finishing activities.
13996                if (Config.LOGV) Log.v(
13997                    TAG, "*** NOW HAVE " + mLruProcesses.size() +
13998                    " of " + curMaxProcs + " processes");
13999                for (   i=0;
14000                        i<mLruProcesses.size()
14001                            && mLruProcesses.size() > curMaxProcs;
14002                        i++) {
14003                    final ProcessRecord app = mLruProcesses.get(i);
14004                    // Quit the application only if we have a state saved for
14005                    // all of its activities.
14006                    boolean canQuit = !app.persistent && app.curReceiver == null
14007                        && app.services.size() == 0
14008                        && app.persistentActivities == 0;
14009                    int NUMA = app.activities.size();
14010                    int j;
14011                    if (Config.LOGV) Log.v(
14012                        TAG, "Looking to quit " + app.processName);
14013                    for (j=0; j<NUMA && canQuit; j++) {
14014                        HistoryRecord r = (HistoryRecord)app.activities.get(j);
14015                        if (Config.LOGV) Log.v(
14016                            TAG, "  " + r.intent.getComponent().flattenToShortString()
14017                            + ": frozen=" + r.haveState + ", visible=" + r.visible);
14018                        canQuit = (r.haveState || !r.stateNotNeeded)
14019                                && !r.visible && r.stopped;
14020                    }
14021                    if (canQuit) {
14022                        // Finish all of the activities, and then the app itself.
14023                        for (j=0; j<NUMA; j++) {
14024                            HistoryRecord r = (HistoryRecord)app.activities.get(j);
14025                            if (!r.finishing) {
14026                                destroyActivityLocked(r, false);
14027                            }
14028                            r.resultTo = null;
14029                        }
14030                        Log.i(TAG, "Exiting application process "
14031                              + app.processName + " ("
14032                              + (app.thread != null ? app.thread.asBinder() : null)
14033                              + ")\n");
14034                        if (app.pid > 0 && app.pid != MY_PID) {
14035                            Process.killProcess(app.pid);
14036                        } else {
14037                            try {
14038                                app.thread.scheduleExit();
14039                            } catch (Exception e) {
14040                                // Ignore exceptions.
14041                            }
14042                        }
14043                        // todo: For now we assume the application is not buggy
14044                        // or evil, and will quit as a result of our request.
14045                        // Eventually we need to drive this off of the death
14046                        // notification, and kill the process if it takes too long.
14047                        cleanUpApplicationRecordLocked(app, false, i);
14048                        i--;
14049                        //dump();
14050                    }
14051                }
14052
14053            }
14054
14055            int curMaxActivities = MAX_ACTIVITIES;
14056            if (mAlwaysFinishActivities) {
14057                curMaxActivities = 1;
14058            }
14059
14060            // Finally, if there are too many activities now running, try to
14061            // finish as many as we can to get back down to the limit.
14062            for (   i=0;
14063                    i<mLRUActivities.size()
14064                        && mLRUActivities.size() > curMaxActivities;
14065                    i++) {
14066                final HistoryRecord r
14067                    = (HistoryRecord)mLRUActivities.get(i);
14068
14069                // We can finish this one if we have its icicle saved and
14070                // it is not persistent.
14071                if ((r.haveState || !r.stateNotNeeded) && !r.visible
14072                        && r.stopped && !r.persistent && !r.finishing) {
14073                    final int origSize = mLRUActivities.size();
14074                    destroyActivityLocked(r, true);
14075
14076                    // This will remove it from the LRU list, so keep
14077                    // our index at the same value.  Note that this check to
14078                    // see if the size changes is just paranoia -- if
14079                    // something unexpected happens, we don't want to end up
14080                    // in an infinite loop.
14081                    if (origSize > mLRUActivities.size()) {
14082                        i--;
14083                    }
14084                }
14085            }
14086        }
14087    }
14088
14089    /** This method sends the specified signal to each of the persistent apps */
14090    public void signalPersistentProcesses(int sig) throws RemoteException {
14091        if (sig != Process.SIGNAL_USR1) {
14092            throw new SecurityException("Only SIGNAL_USR1 is allowed");
14093        }
14094
14095        synchronized (this) {
14096            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
14097                    != PackageManager.PERMISSION_GRANTED) {
14098                throw new SecurityException("Requires permission "
14099                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
14100            }
14101
14102            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
14103                ProcessRecord r = mLruProcesses.get(i);
14104                if (r.thread != null && r.persistent) {
14105                    Process.sendSignal(r.pid, sig);
14106                }
14107            }
14108        }
14109    }
14110
14111    public boolean profileControl(String process, boolean start,
14112            String path, ParcelFileDescriptor fd) throws RemoteException {
14113
14114        try {
14115            synchronized (this) {
14116                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
14117                // its own permission.
14118                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14119                        != PackageManager.PERMISSION_GRANTED) {
14120                    throw new SecurityException("Requires permission "
14121                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
14122                }
14123
14124                if (start && fd == null) {
14125                    throw new IllegalArgumentException("null fd");
14126                }
14127
14128                ProcessRecord proc = null;
14129                try {
14130                    int pid = Integer.parseInt(process);
14131                    synchronized (mPidsSelfLocked) {
14132                        proc = mPidsSelfLocked.get(pid);
14133                    }
14134                } catch (NumberFormatException e) {
14135                }
14136
14137                if (proc == null) {
14138                    HashMap<String, SparseArray<ProcessRecord>> all
14139                            = mProcessNames.getMap();
14140                    SparseArray<ProcessRecord> procs = all.get(process);
14141                    if (procs != null && procs.size() > 0) {
14142                        proc = procs.valueAt(0);
14143                    }
14144                }
14145
14146                if (proc == null || proc.thread == null) {
14147                    throw new IllegalArgumentException("Unknown process: " + process);
14148                }
14149
14150                boolean isSecure = "1".equals(SystemProperties.get(SYSTEM_SECURE, "0"));
14151                if (isSecure) {
14152                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
14153                        throw new SecurityException("Process not debuggable: " + proc);
14154                    }
14155                }
14156
14157                proc.thread.profilerControl(start, path, fd);
14158                fd = null;
14159                return true;
14160            }
14161        } catch (RemoteException e) {
14162            throw new IllegalStateException("Process disappeared");
14163        } finally {
14164            if (fd != null) {
14165                try {
14166                    fd.close();
14167                } catch (IOException e) {
14168                }
14169            }
14170        }
14171    }
14172
14173    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
14174    public void monitor() {
14175        synchronized (this) { }
14176    }
14177}
14178