ActivityManagerService.java revision dc6b635cfa440454985461444c3cf1da8078cee1
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 android.app.Activity;
29import android.app.ActivityManager;
30import android.app.ActivityManagerNative;
31import android.app.ActivityThread;
32import android.app.AlertDialog;
33import android.app.ApplicationErrorReport;
34import android.app.Dialog;
35import android.app.IActivityController;
36import android.app.IActivityWatcher;
37import android.app.IApplicationThread;
38import android.app.IInstrumentationWatcher;
39import android.app.IServiceConnection;
40import android.app.IThumbnailReceiver;
41import android.app.Instrumentation;
42import android.app.Notification;
43import android.app.PendingIntent;
44import android.app.ResultInfo;
45import android.app.Service;
46import android.backup.IBackupManager;
47import android.content.ActivityNotFoundException;
48import android.content.ComponentName;
49import android.content.ContentResolver;
50import android.content.Context;
51import android.content.Intent;
52import android.content.IntentFilter;
53import android.content.IIntentReceiver;
54import android.content.IIntentSender;
55import android.content.IntentSender;
56import android.content.pm.ActivityInfo;
57import android.content.pm.ApplicationInfo;
58import android.content.pm.ConfigurationInfo;
59import android.content.pm.IPackageDataObserver;
60import android.content.pm.IPackageManager;
61import android.content.pm.InstrumentationInfo;
62import android.content.pm.PackageManager;
63import android.content.pm.PathPermission;
64import android.content.pm.ProviderInfo;
65import android.content.pm.ResolveInfo;
66import android.content.pm.ServiceInfo;
67import android.content.res.Configuration;
68import android.graphics.Bitmap;
69import android.net.Uri;
70import android.os.Binder;
71import android.os.Bundle;
72import android.os.Debug;
73import android.os.Environment;
74import android.os.FileUtils;
75import android.os.Handler;
76import android.os.IBinder;
77import android.os.IPermissionController;
78import android.os.Looper;
79import android.os.Message;
80import android.os.Parcel;
81import android.os.ParcelFileDescriptor;
82import android.os.PowerManager;
83import android.os.Process;
84import android.os.RemoteCallbackList;
85import android.os.RemoteException;
86import android.os.ServiceManager;
87import android.os.SystemClock;
88import android.os.SystemProperties;
89import android.provider.Checkin;
90import android.provider.Settings;
91import android.server.data.CrashData;
92import android.server.data.StackTraceElementData;
93import android.server.data.ThrowableData;
94import android.text.TextUtils;
95import android.util.Config;
96import android.util.EventLog;
97import android.util.Log;
98import android.util.PrintWriterPrinter;
99import android.util.SparseArray;
100import android.view.Gravity;
101import android.view.LayoutInflater;
102import android.view.View;
103import android.view.WindowManager;
104import android.view.WindowManagerPolicy;
105
106import dalvik.system.Zygote;
107
108import java.io.ByteArrayInputStream;
109import java.io.DataInputStream;
110import java.io.File;
111import java.io.FileDescriptor;
112import java.io.FileInputStream;
113import java.io.FileNotFoundException;
114import java.io.IOException;
115import java.io.PrintWriter;
116import java.lang.IllegalStateException;
117import java.lang.ref.WeakReference;
118import java.util.ArrayList;
119import java.util.HashMap;
120import java.util.HashSet;
121import java.util.Iterator;
122import java.util.List;
123import java.util.Locale;
124import java.util.Map;
125
126public final class ActivityManagerService extends ActivityManagerNative implements Watchdog.Monitor {
127    static final String TAG = "ActivityManager";
128    static final boolean DEBUG = false;
129    static final boolean localLOGV = DEBUG ? Config.LOGD : Config.LOGV;
130    static final boolean DEBUG_SWITCH = localLOGV || false;
131    static final boolean DEBUG_TASKS = localLOGV || false;
132    static final boolean DEBUG_PAUSE = localLOGV || false;
133    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
134    static final boolean DEBUG_TRANSITION = localLOGV || false;
135    static final boolean DEBUG_BROADCAST = localLOGV || false;
136    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
137    static final boolean DEBUG_SERVICE = localLOGV || false;
138    static final boolean DEBUG_VISBILITY = localLOGV || false;
139    static final boolean DEBUG_PROCESSES = localLOGV || false;
140    static final boolean DEBUG_PROVIDER = localLOGV || false;
141    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
142    static final boolean DEBUG_RESULTS = localLOGV || false;
143    static final boolean DEBUG_BACKUP = localLOGV || true;
144    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
145    static final boolean VALIDATE_TOKENS = false;
146    static final boolean SHOW_ACTIVITY_START_TIME = true;
147
148    // Control over CPU and battery monitoring.
149    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
150    static final boolean MONITOR_CPU_USAGE = true;
151    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
152    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
153    static final boolean MONITOR_THREAD_CPU_USAGE = false;
154
155    // Event log tags
156    static final int LOG_CONFIGURATION_CHANGED = 2719;
157    static final int LOG_CPU = 2721;
158    static final int LOG_AM_FINISH_ACTIVITY = 30001;
159    static final int LOG_TASK_TO_FRONT = 30002;
160    static final int LOG_AM_NEW_INTENT = 30003;
161    static final int LOG_AM_CREATE_TASK = 30004;
162    static final int LOG_AM_CREATE_ACTIVITY = 30005;
163    static final int LOG_AM_RESTART_ACTIVITY = 30006;
164    static final int LOG_AM_RESUME_ACTIVITY = 30007;
165    static final int LOG_ANR = 30008;
166    static final int LOG_ACTIVITY_LAUNCH_TIME = 30009;
167    static final int LOG_AM_PROCESS_BOUND = 30010;
168    static final int LOG_AM_PROCESS_DIED = 30011;
169    static final int LOG_AM_FAILED_TO_PAUSE_ACTIVITY = 30012;
170    static final int LOG_AM_PAUSE_ACTIVITY = 30013;
171    static final int LOG_AM_PROCESS_START = 30014;
172    static final int LOG_AM_PROCESS_BAD = 30015;
173    static final int LOG_AM_PROCESS_GOOD = 30016;
174    static final int LOG_AM_LOW_MEMORY = 30017;
175    static final int LOG_AM_DESTROY_ACTIVITY = 30018;
176    static final int LOG_AM_RELAUNCH_RESUME_ACTIVITY = 30019;
177    static final int LOG_AM_RELAUNCH_ACTIVITY = 30020;
178    static final int LOG_AM_KILL_FOR_MEMORY = 30023;
179    static final int LOG_AM_BROADCAST_DISCARD_FILTER = 30024;
180    static final int LOG_AM_BROADCAST_DISCARD_APP = 30025;
181    static final int LOG_AM_CREATE_SERVICE = 30030;
182    static final int LOG_AM_DESTROY_SERVICE = 30031;
183    static final int LOG_AM_PROCESS_CRASHED_TOO_MUCH = 30032;
184    static final int LOG_AM_DROP_PROCESS = 30033;
185    static final int LOG_AM_SERVICE_CRASHED_TOO_MUCH = 30034;
186    static final int LOG_AM_SCHEDULE_SERVICE_RESTART = 30035;
187    static final int LOG_AM_PROVIDER_LOST_PROCESS = 30036;
188
189    static final int LOG_BOOT_PROGRESS_AMS_READY = 3040;
190    static final int LOG_BOOT_PROGRESS_ENABLE_SCREEN = 3050;
191
192    // The flags that are set for all calls we make to the package manager.
193    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
194
195    private static final String SYSTEM_SECURE = "ro.secure";
196
197    // This is the maximum number of application processes we would like
198    // to have running.  Due to the asynchronous nature of things, we can
199    // temporarily go beyond this limit.
200    static final int MAX_PROCESSES = 2;
201
202    // Set to false to leave processes running indefinitely, relying on
203    // the kernel killing them as resources are required.
204    static final boolean ENFORCE_PROCESS_LIMIT = false;
205
206    // This is the maximum number of activities that we would like to have
207    // running at a given time.
208    static final int MAX_ACTIVITIES = 20;
209
210    // Maximum number of recent tasks that we can remember.
211    static final int MAX_RECENT_TASKS = 20;
212
213    // Amount of time after a call to stopAppSwitches() during which we will
214    // prevent further untrusted switches from happening.
215    static final long APP_SWITCH_DELAY_TIME = 5*1000;
216
217    // How long until we reset a task when the user returns to it.  Currently
218    // 30 minutes.
219    static final long ACTIVITY_INACTIVE_RESET_TIME = 1000*60*30;
220
221    // Set to true to disable the icon that is shown while a new activity
222    // is being started.
223    static final boolean SHOW_APP_STARTING_ICON = true;
224
225    // How long we wait until giving up on the last activity to pause.  This
226    // is short because it directly impacts the responsiveness of starting the
227    // next activity.
228    static final int PAUSE_TIMEOUT = 500;
229
230    /**
231     * How long we can hold the launch wake lock before giving up.
232     */
233    static final int LAUNCH_TIMEOUT = 10*1000;
234
235    // How long we wait for a launched process to attach to the activity manager
236    // before we decide it's never going to come up for real.
237    static final int PROC_START_TIMEOUT = 10*1000;
238
239    // How long we wait until giving up on the last activity telling us it
240    // is idle.
241    static final int IDLE_TIMEOUT = 10*1000;
242
243    // How long to wait after going idle before forcing apps to GC.
244    static final int GC_TIMEOUT = 5*1000;
245
246    // The minimum amount of time between successive GC requests for a process.
247    static final int GC_MIN_INTERVAL = 60*1000;
248
249    // How long we wait until giving up on an activity telling us it has
250    // finished destroying itself.
251    static final int DESTROY_TIMEOUT = 10*1000;
252
253    // How long we allow a receiver to run before giving up on it.
254    static final int BROADCAST_TIMEOUT = 10*1000;
255
256    // How long we wait for a service to finish executing.
257    static final int SERVICE_TIMEOUT = 20*1000;
258
259    // How long a service needs to be running until restarting its process
260    // is no longer considered to be a relaunch of the service.
261    static final int SERVICE_RESTART_DURATION = 5*1000;
262
263    // How long a service needs to be running until it will start back at
264    // SERVICE_RESTART_DURATION after being killed.
265    static final int SERVICE_RESET_RUN_DURATION = 60*1000;
266
267    // Multiplying factor to increase restart duration time by, for each time
268    // a service is killed before it has run for SERVICE_RESET_RUN_DURATION.
269    static final int SERVICE_RESTART_DURATION_FACTOR = 4;
270
271    // The minimum amount of time between restarting services that we allow.
272    // That is, when multiple services are restarting, we won't allow each
273    // to restart less than this amount of time from the last one.
274    static final int SERVICE_MIN_RESTART_TIME_BETWEEN = 10*1000;
275
276    // Maximum amount of time for there to be no activity on a service before
277    // we consider it non-essential and allow its process to go on the
278    // LRU background list.
279    static final int MAX_SERVICE_INACTIVITY = 30*60*1000;
280
281    // How long we wait until we timeout on key dispatching.
282    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
283
284    // The minimum time we allow between crashes, for us to consider this
285    // application to be bad and stop and its services and reject broadcasts.
286    static final int MIN_CRASH_INTERVAL = 60*1000;
287
288    // How long we wait until we timeout on key dispatching during instrumentation.
289    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
290
291    // OOM adjustments for processes in various states:
292
293    // This is a process without anything currently running in it.  Definitely
294    // the first to go! Value set in system/rootdir/init.rc on startup.
295    // This value is initalized in the constructor, careful when refering to
296    // this static variable externally.
297    static int EMPTY_APP_ADJ;
298
299    // This is a process with a content provider that does not have any clients
300    // attached to it.  If it did have any clients, its adjustment would be the
301    // one for the highest-priority of those processes.
302    static int CONTENT_PROVIDER_ADJ;
303
304    // This is a process only hosting activities that are not visible,
305    // so it can be killed without any disruption. Value set in
306    // system/rootdir/init.rc on startup.
307    final int HIDDEN_APP_MAX_ADJ;
308    static int HIDDEN_APP_MIN_ADJ;
309
310    // This is a process holding the home application -- we want to try
311    // avoiding killing it, even if it would normally be in the background,
312    // because the user interacts with it so much.
313    final int HOME_APP_ADJ;
314
315    // This is a process currently hosting a backup operation.  Killing it
316    // is not entirely fatal but is generally a bad idea.
317    final int BACKUP_APP_ADJ;
318
319    // This is a process holding a secondary server -- killing it will not
320    // have much of an impact as far as the user is concerned. Value set in
321    // system/rootdir/init.rc on startup.
322    final int SECONDARY_SERVER_ADJ;
323
324    // This is a process only hosting activities that are visible to the
325    // user, so we'd prefer they don't disappear. Value set in
326    // system/rootdir/init.rc on startup.
327    final int VISIBLE_APP_ADJ;
328
329    // This is the process running the current foreground app.  We'd really
330    // rather not kill it! Value set in system/rootdir/init.rc on startup.
331    final int FOREGROUND_APP_ADJ;
332
333    // This is a process running a core server, such as telephony.  Definitely
334    // don't want to kill it, but doing so is not completely fatal.
335    static final int CORE_SERVER_ADJ = -12;
336
337    // The system process runs at the default adjustment.
338    static final int SYSTEM_ADJ = -16;
339
340    // Memory pages are 4K.
341    static final int PAGE_SIZE = 4*1024;
342
343    // System property defining error report receiver for system apps
344    static final String SYSTEM_APPS_ERROR_RECEIVER_PROPERTY = "ro.error.receiver.system.apps";
345
346    // System property defining default error report receiver
347    static final String DEFAULT_ERROR_RECEIVER_PROPERTY = "ro.error.receiver.default";
348
349    // Corresponding memory levels for above adjustments.
350    final int EMPTY_APP_MEM;
351    final int HIDDEN_APP_MEM;
352    final int HOME_APP_MEM;
353    final int BACKUP_APP_MEM;
354    final int SECONDARY_SERVER_MEM;
355    final int VISIBLE_APP_MEM;
356    final int FOREGROUND_APP_MEM;
357
358    final int MY_PID;
359
360    static final String[] EMPTY_STRING_ARRAY = new String[0];
361
362    enum ActivityState {
363        INITIALIZING,
364        RESUMED,
365        PAUSING,
366        PAUSED,
367        STOPPING,
368        STOPPED,
369        FINISHING,
370        DESTROYING,
371        DESTROYED
372    }
373
374    /**
375     * The back history of all previous (and possibly still
376     * running) activities.  It contains HistoryRecord objects.
377     */
378    final ArrayList mHistory = new ArrayList();
379
380    /**
381     * Description of a request to start a new activity, which has been held
382     * due to app switches being disabled.
383     */
384    class PendingActivityLaunch {
385        HistoryRecord r;
386        HistoryRecord sourceRecord;
387        Uri[] grantedUriPermissions;
388        int grantedMode;
389        boolean onlyIfNeeded;
390    }
391
392    final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
393            = new ArrayList<PendingActivityLaunch>();
394
395    /**
396     * List of all active broadcasts that are to be executed immediately
397     * (without waiting for another broadcast to finish).  Currently this only
398     * contains broadcasts to registered receivers, to avoid spinning up
399     * a bunch of processes to execute IntentReceiver components.
400     */
401    final ArrayList<BroadcastRecord> mParallelBroadcasts
402            = new ArrayList<BroadcastRecord>();
403
404    /**
405     * List of all active broadcasts that are to be executed one at a time.
406     * The object at the top of the list is the currently activity broadcasts;
407     * those after it are waiting for the top to finish..
408     */
409    final ArrayList<BroadcastRecord> mOrderedBroadcasts
410            = new ArrayList<BroadcastRecord>();
411
412    /**
413     * Set when we current have a BROADCAST_INTENT_MSG in flight.
414     */
415    boolean mBroadcastsScheduled = false;
416
417    /**
418     * Set to indicate whether to issue an onUserLeaving callback when a
419     * newly launched activity is being brought in front of us.
420     */
421    boolean mUserLeaving = false;
422
423    /**
424     * When we are in the process of pausing an activity, before starting the
425     * next one, this variable holds the activity that is currently being paused.
426     */
427    HistoryRecord mPausingActivity = null;
428
429    /**
430     * Current activity that is resumed, or null if there is none.
431     */
432    HistoryRecord mResumedActivity = null;
433
434    /**
435     * Activity we have told the window manager to have key focus.
436     */
437    HistoryRecord mFocusedActivity = null;
438
439    /**
440     * This is the last activity that we put into the paused state.  This is
441     * used to determine if we need to do an activity transition while sleeping,
442     * when we normally hold the top activity paused.
443     */
444    HistoryRecord mLastPausedActivity = null;
445
446    /**
447     * List of activities that are waiting for a new activity
448     * to become visible before completing whatever operation they are
449     * supposed to do.
450     */
451    final ArrayList mWaitingVisibleActivities = new ArrayList();
452
453    /**
454     * List of activities that are ready to be stopped, but waiting
455     * for the next activity to settle down before doing so.  It contains
456     * HistoryRecord objects.
457     */
458    final ArrayList<HistoryRecord> mStoppingActivities
459            = new ArrayList<HistoryRecord>();
460
461    /**
462     * Animations that for the current transition have requested not to
463     * be considered for the transition animation.
464     */
465    final ArrayList<HistoryRecord> mNoAnimActivities
466            = new ArrayList<HistoryRecord>();
467
468    /**
469     * List of intents that were used to start the most recent tasks.
470     */
471    final ArrayList<TaskRecord> mRecentTasks
472            = new ArrayList<TaskRecord>();
473
474    /**
475     * List of activities that are ready to be finished, but waiting
476     * for the previous activity to settle down before doing so.  It contains
477     * HistoryRecord objects.
478     */
479    final ArrayList mFinishingActivities = new ArrayList();
480
481    /**
482     * All of the applications we currently have running organized by name.
483     * The keys are strings of the application package name (as
484     * returned by the package manager), and the keys are ApplicationRecord
485     * objects.
486     */
487    final ProcessMap<ProcessRecord> mProcessNames
488            = new ProcessMap<ProcessRecord>();
489
490    /**
491     * The last time that various processes have crashed.
492     */
493    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
494
495    /**
496     * Set of applications that we consider to be bad, and will reject
497     * incoming broadcasts from (which the user has no control over).
498     * Processes are added to this set when they have crashed twice within
499     * a minimum amount of time; they are removed from it when they are
500     * later restarted (hopefully due to some user action).  The value is the
501     * time it was added to the list.
502     */
503    final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>();
504
505    /**
506     * All of the processes we currently have running organized by pid.
507     * The keys are the pid running the application.
508     *
509     * <p>NOTE: This object is protected by its own lock, NOT the global
510     * activity manager lock!
511     */
512    final SparseArray<ProcessRecord> mPidsSelfLocked
513            = new SparseArray<ProcessRecord>();
514
515    /**
516     * All of the processes that have been forced to be foreground.  The key
517     * is the pid of the caller who requested it (we hold a death
518     * link on it).
519     */
520    abstract class ForegroundToken implements IBinder.DeathRecipient {
521        int pid;
522        IBinder token;
523    }
524    final SparseArray<ForegroundToken> mForegroundProcesses
525            = new SparseArray<ForegroundToken>();
526
527    /**
528     * List of records for processes that someone had tried to start before the
529     * system was ready.  We don't start them at that point, but ensure they
530     * are started by the time booting is complete.
531     */
532    final ArrayList<ProcessRecord> mProcessesOnHold
533            = new ArrayList<ProcessRecord>();
534
535    /**
536     * List of records for processes that we have started and are waiting
537     * for them to call back.  This is really only needed when running in
538     * single processes mode, in which case we do not have a unique pid for
539     * each process.
540     */
541    final ArrayList<ProcessRecord> mStartingProcesses
542            = new ArrayList<ProcessRecord>();
543
544    /**
545     * List of persistent applications that are in the process
546     * of being started.
547     */
548    final ArrayList<ProcessRecord> mPersistentStartingProcesses
549            = new ArrayList<ProcessRecord>();
550
551    /**
552     * Processes that are being forcibly torn down.
553     */
554    final ArrayList<ProcessRecord> mRemovedProcesses
555            = new ArrayList<ProcessRecord>();
556
557    /**
558     * List of running applications, sorted by recent usage.
559     * The first entry in the list is the least recently used.
560     * It contains ApplicationRecord objects.  This list does NOT include
561     * any persistent application records (since we never want to exit them).
562     */
563    final ArrayList<ProcessRecord> mLRUProcesses
564            = new ArrayList<ProcessRecord>();
565
566    /**
567     * List of processes that should gc as soon as things are idle.
568     */
569    final ArrayList<ProcessRecord> mProcessesToGc
570            = new ArrayList<ProcessRecord>();
571
572    /**
573     * This is the process holding what we currently consider to be
574     * the "home" activity.
575     */
576    private ProcessRecord mHomeProcess;
577
578    /**
579     * List of running activities, sorted by recent usage.
580     * The first entry in the list is the least recently used.
581     * It contains HistoryRecord objects.
582     */
583    private final ArrayList mLRUActivities = new ArrayList();
584
585    /**
586     * Set of PendingResultRecord objects that are currently active.
587     */
588    final HashSet mPendingResultRecords = new HashSet();
589
590    /**
591     * Set of IntentSenderRecord objects that are currently active.
592     */
593    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
594            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
595
596    /**
597     * Intent broadcast that we have tried to start, but are
598     * waiting for its application's process to be created.  We only
599     * need one (instead of a list) because we always process broadcasts
600     * one at a time, so no others can be started while waiting for this
601     * one.
602     */
603    BroadcastRecord mPendingBroadcast = null;
604
605    /**
606     * Keeps track of all IIntentReceivers that have been registered for
607     * broadcasts.  Hash keys are the receiver IBinder, hash value is
608     * a ReceiverList.
609     */
610    final HashMap mRegisteredReceivers = new HashMap();
611
612    /**
613     * Resolver for broadcast intents to registered receivers.
614     * Holds BroadcastFilter (subclass of IntentFilter).
615     */
616    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
617            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
618        @Override
619        protected boolean allowFilterResult(
620                BroadcastFilter filter, List<BroadcastFilter> dest) {
621            IBinder target = filter.receiverList.receiver.asBinder();
622            for (int i=dest.size()-1; i>=0; i--) {
623                if (dest.get(i).receiverList.receiver.asBinder() == target) {
624                    return false;
625                }
626            }
627            return true;
628        }
629    };
630
631    /**
632     * State of all active sticky broadcasts.  Keys are the action of the
633     * sticky Intent, values are an ArrayList of all broadcasted intents with
634     * that action (which should usually be one).
635     */
636    final HashMap<String, ArrayList<Intent>> mStickyBroadcasts =
637            new HashMap<String, ArrayList<Intent>>();
638
639    /**
640     * All currently running services.
641     */
642    final HashMap<ComponentName, ServiceRecord> mServices =
643        new HashMap<ComponentName, ServiceRecord>();
644
645    /**
646     * All currently running services indexed by the Intent used to start them.
647     */
648    final HashMap<Intent.FilterComparison, ServiceRecord> mServicesByIntent =
649        new HashMap<Intent.FilterComparison, ServiceRecord>();
650
651    /**
652     * All currently bound service connections.  Keys are the IBinder of
653     * the client's IServiceConnection.
654     */
655    final HashMap<IBinder, ConnectionRecord> mServiceConnections
656            = new HashMap<IBinder, ConnectionRecord>();
657
658    /**
659     * List of services that we have been asked to start,
660     * but haven't yet been able to.  It is used to hold start requests
661     * while waiting for their corresponding application thread to get
662     * going.
663     */
664    final ArrayList<ServiceRecord> mPendingServices
665            = new ArrayList<ServiceRecord>();
666
667    /**
668     * List of services that are scheduled to restart following a crash.
669     */
670    final ArrayList<ServiceRecord> mRestartingServices
671            = new ArrayList<ServiceRecord>();
672
673    /**
674     * List of services that are in the process of being stopped.
675     */
676    final ArrayList<ServiceRecord> mStoppingServices
677            = new ArrayList<ServiceRecord>();
678
679    /**
680     * Backup/restore process management
681     */
682    String mBackupAppName = null;
683    BackupRecord mBackupTarget = null;
684
685    /**
686     * List of PendingThumbnailsRecord objects of clients who are still
687     * waiting to receive all of the thumbnails for a task.
688     */
689    final ArrayList mPendingThumbnails = new ArrayList();
690
691    /**
692     * List of HistoryRecord objects that have been finished and must
693     * still report back to a pending thumbnail receiver.
694     */
695    final ArrayList mCancelledThumbnails = new ArrayList();
696
697    /**
698     * All of the currently running global content providers.  Keys are a
699     * string containing the provider name and values are a
700     * ContentProviderRecord object containing the data about it.  Note
701     * that a single provider may be published under multiple names, so
702     * there may be multiple entries here for a single one in mProvidersByClass.
703     */
704    final HashMap mProvidersByName = new HashMap();
705
706    /**
707     * All of the currently running global content providers.  Keys are a
708     * string containing the provider's implementation class and values are a
709     * ContentProviderRecord object containing the data about it.
710     */
711    final HashMap mProvidersByClass = new HashMap();
712
713    /**
714     * List of content providers who have clients waiting for them.  The
715     * application is currently being launched and the provider will be
716     * removed from this list once it is published.
717     */
718    final ArrayList mLaunchingProviders = new ArrayList();
719
720    /**
721     * Global set of specific Uri permissions that have been granted.
722     */
723    final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions
724            = new SparseArray<HashMap<Uri, UriPermission>>();
725
726    /**
727     * Thread-local storage used to carry caller permissions over through
728     * indirect content-provider access.
729     * @see #ActivityManagerService.openContentUri()
730     */
731    private class Identity {
732        public int pid;
733        public int uid;
734
735        Identity(int _pid, int _uid) {
736            pid = _pid;
737            uid = _uid;
738        }
739    }
740    private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
741
742    /**
743     * All information we have collected about the runtime performance of
744     * any user id that can impact battery performance.
745     */
746    final BatteryStatsService mBatteryStatsService;
747
748    /**
749     * information about component usage
750     */
751    final UsageStatsService mUsageStatsService;
752
753    /**
754     * Current configuration information.  HistoryRecord objects are given
755     * a reference to this object to indicate which configuration they are
756     * currently running in, so this object must be kept immutable.
757     */
758    Configuration mConfiguration = new Configuration();
759
760    /**
761     * Hardware-reported OpenGLES version.
762     */
763    final int GL_ES_VERSION;
764
765    /**
766     * List of initialization arguments to pass to all processes when binding applications to them.
767     * For example, references to the commonly used services.
768     */
769    HashMap<String, IBinder> mAppBindArgs;
770
771    /**
772     * Temporary to avoid allocations.  Protected by main lock.
773     */
774    final StringBuilder mStringBuilder = new StringBuilder(256);
775
776    /**
777     * Used to control how we initialize the service.
778     */
779    boolean mStartRunning = false;
780    ComponentName mTopComponent;
781    String mTopAction;
782    String mTopData;
783    boolean mSystemReady = false;
784    boolean mBooting = false;
785    boolean mWaitingUpdate = false;
786    boolean mDidUpdate = false;
787
788    Context mContext;
789
790    int mFactoryTest;
791
792    boolean mCheckedForSetup;
793
794    /**
795     * The time at which we will allow normal application switches again,
796     * after a call to {@link #stopAppSwitches()}.
797     */
798    long mAppSwitchesAllowedTime;
799
800    /**
801     * This is set to true after the first switch after mAppSwitchesAllowedTime
802     * is set; any switches after that will clear the time.
803     */
804    boolean mDidAppSwitch;
805
806    /**
807     * Set while we are wanting to sleep, to prevent any
808     * activities from being started/resumed.
809     */
810    boolean mSleeping = false;
811
812    /**
813     * Set if we are shutting down the system, similar to sleeping.
814     */
815    boolean mShuttingDown = false;
816
817    /**
818     * Set when the system is going to sleep, until we have
819     * successfully paused the current activity and released our wake lock.
820     * At that point the system is allowed to actually sleep.
821     */
822    PowerManager.WakeLock mGoingToSleep;
823
824    /**
825     * We don't want to allow the device to go to sleep while in the process
826     * of launching an activity.  This is primarily to allow alarm intent
827     * receivers to launch an activity and get that to run before the device
828     * goes back to sleep.
829     */
830    PowerManager.WakeLock mLaunchingActivity;
831
832    /**
833     * Task identifier that activities are currently being started
834     * in.  Incremented each time a new task is created.
835     * todo: Replace this with a TokenSpace class that generates non-repeating
836     * integers that won't wrap.
837     */
838    int mCurTask = 1;
839
840    /**
841     * Current sequence id for oom_adj computation traversal.
842     */
843    int mAdjSeq = 0;
844
845    /**
846     * Set to true if the ANDROID_SIMPLE_PROCESS_MANAGEMENT envvar
847     * is set, indicating the user wants processes started in such a way
848     * that they can use ANDROID_PROCESS_WRAPPER and know what will be
849     * running in each process (thus no pre-initialized process, etc).
850     */
851    boolean mSimpleProcessManagement = false;
852
853    /**
854     * System monitoring: number of processes that died since the last
855     * N procs were started.
856     */
857    int[] mProcDeaths = new int[20];
858
859    /**
860     * This is set if we had to do a delayed dexopt of an app before launching
861     * it, to increasing the ANR timeouts in that case.
862     */
863    boolean mDidDexOpt;
864
865    String mDebugApp = null;
866    boolean mWaitForDebugger = false;
867    boolean mDebugTransient = false;
868    String mOrigDebugApp = null;
869    boolean mOrigWaitForDebugger = false;
870    boolean mAlwaysFinishActivities = false;
871    IActivityController mController = null;
872
873    final RemoteCallbackList<IActivityWatcher> mWatchers
874            = new RemoteCallbackList<IActivityWatcher>();
875
876    /**
877     * Callback of last caller to {@link #requestPss}.
878     */
879    Runnable mRequestPssCallback;
880
881    /**
882     * Remaining processes for which we are waiting results from the last
883     * call to {@link #requestPss}.
884     */
885    final ArrayList<ProcessRecord> mRequestPssList
886            = new ArrayList<ProcessRecord>();
887
888    /**
889     * Runtime statistics collection thread.  This object's lock is used to
890     * protect all related state.
891     */
892    final Thread mProcessStatsThread;
893
894    /**
895     * Used to collect process stats when showing not responding dialog.
896     * Protected by mProcessStatsThread.
897     */
898    final ProcessStats mProcessStats = new ProcessStats(
899            MONITOR_THREAD_CPU_USAGE);
900    long mLastCpuTime = 0;
901    long mLastWriteTime = 0;
902
903    long mInitialStartTime = 0;
904
905    /**
906     * Set to true after the system has finished booting.
907     */
908    boolean mBooted = false;
909
910    int mProcessLimit = 0;
911
912    WindowManagerService mWindowManager;
913
914    static ActivityManagerService mSelf;
915    static ActivityThread mSystemThread;
916
917    private final class AppDeathRecipient implements IBinder.DeathRecipient {
918        final ProcessRecord mApp;
919        final int mPid;
920        final IApplicationThread mAppThread;
921
922        AppDeathRecipient(ProcessRecord app, int pid,
923                IApplicationThread thread) {
924            if (localLOGV) Log.v(
925                TAG, "New death recipient " + this
926                + " for thread " + thread.asBinder());
927            mApp = app;
928            mPid = pid;
929            mAppThread = thread;
930        }
931
932        public void binderDied() {
933            if (localLOGV) Log.v(
934                TAG, "Death received in " + this
935                + " for thread " + mAppThread.asBinder());
936            removeRequestedPss(mApp);
937            synchronized(ActivityManagerService.this) {
938                appDiedLocked(mApp, mPid, mAppThread);
939            }
940        }
941    }
942
943    static final int SHOW_ERROR_MSG = 1;
944    static final int SHOW_NOT_RESPONDING_MSG = 2;
945    static final int SHOW_FACTORY_ERROR_MSG = 3;
946    static final int UPDATE_CONFIGURATION_MSG = 4;
947    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
948    static final int WAIT_FOR_DEBUGGER_MSG = 6;
949    static final int BROADCAST_INTENT_MSG = 7;
950    static final int BROADCAST_TIMEOUT_MSG = 8;
951    static final int PAUSE_TIMEOUT_MSG = 9;
952    static final int IDLE_TIMEOUT_MSG = 10;
953    static final int IDLE_NOW_MSG = 11;
954    static final int SERVICE_TIMEOUT_MSG = 12;
955    static final int UPDATE_TIME_ZONE = 13;
956    static final int SHOW_UID_ERROR_MSG = 14;
957    static final int IM_FEELING_LUCKY_MSG = 15;
958    static final int LAUNCH_TIMEOUT_MSG = 16;
959    static final int DESTROY_TIMEOUT_MSG = 17;
960    static final int SERVICE_ERROR_MSG = 18;
961    static final int RESUME_TOP_ACTIVITY_MSG = 19;
962    static final int PROC_START_TIMEOUT_MSG = 20;
963    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
964    static final int KILL_APPLICATION_MSG = 22;
965
966    AlertDialog mUidAlert;
967
968    final Handler mHandler = new Handler() {
969        //public Handler() {
970        //    if (localLOGV) Log.v(TAG, "Handler started!");
971        //}
972
973        public void handleMessage(Message msg) {
974            switch (msg.what) {
975            case SHOW_ERROR_MSG: {
976                HashMap data = (HashMap) msg.obj;
977                byte[] crashData = (byte[])data.get("crashData");
978                if (crashData != null) {
979                    // This needs to be *un*synchronized to avoid deadlock.
980                    ContentResolver resolver = mContext.getContentResolver();
981                    Checkin.reportCrash(resolver, crashData);
982                }
983                synchronized (ActivityManagerService.this) {
984                    ProcessRecord proc = (ProcessRecord)data.get("app");
985                    if (proc != null && proc.crashDialog != null) {
986                        Log.e(TAG, "App already has crash dialog: " + proc);
987                        return;
988                    }
989                    AppErrorResult res = (AppErrorResult) data.get("result");
990                    if (!mSleeping && !mShuttingDown) {
991                        Dialog d = new AppErrorDialog(
992                                mContext, res, proc,
993                                (Integer)data.get("flags"),
994                                (String)data.get("shortMsg"),
995                                (String)data.get("longMsg"));
996                        d.show();
997                        proc.crashDialog = d;
998                    } else {
999                        // The device is asleep, so just pretend that the user
1000                        // saw a crash dialog and hit "force quit".
1001                        res.set(0);
1002                    }
1003                }
1004
1005                ensureBootCompleted();
1006            } break;
1007            case SHOW_NOT_RESPONDING_MSG: {
1008                synchronized (ActivityManagerService.this) {
1009                    HashMap data = (HashMap) msg.obj;
1010                    ProcessRecord proc = (ProcessRecord)data.get("app");
1011                    if (proc != null && proc.anrDialog != null) {
1012                        Log.e(TAG, "App already has anr dialog: " + proc);
1013                        return;
1014                    }
1015
1016                    broadcastIntentLocked(null, null, new Intent("android.intent.action.ANR"),
1017                            null, null, 0, null, null, null,
1018                            false, false, MY_PID, Process.SYSTEM_UID);
1019
1020                    Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1021                            mContext, proc, (HistoryRecord)data.get("activity"));
1022                    d.show();
1023                    proc.anrDialog = d;
1024                }
1025
1026                ensureBootCompleted();
1027            } break;
1028            case SHOW_FACTORY_ERROR_MSG: {
1029                Dialog d = new FactoryErrorDialog(
1030                    mContext, msg.getData().getCharSequence("msg"));
1031                d.show();
1032                ensureBootCompleted();
1033            } break;
1034            case UPDATE_CONFIGURATION_MSG: {
1035                final ContentResolver resolver = mContext.getContentResolver();
1036                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1037            } break;
1038            case GC_BACKGROUND_PROCESSES_MSG: {
1039                synchronized (ActivityManagerService.this) {
1040                    performAppGcsIfAppropriateLocked();
1041                }
1042            } break;
1043            case WAIT_FOR_DEBUGGER_MSG: {
1044                synchronized (ActivityManagerService.this) {
1045                    ProcessRecord app = (ProcessRecord)msg.obj;
1046                    if (msg.arg1 != 0) {
1047                        if (!app.waitedForDebugger) {
1048                            Dialog d = new AppWaitingForDebuggerDialog(
1049                                    ActivityManagerService.this,
1050                                    mContext, app);
1051                            app.waitDialog = d;
1052                            app.waitedForDebugger = true;
1053                            d.show();
1054                        }
1055                    } else {
1056                        if (app.waitDialog != null) {
1057                            app.waitDialog.dismiss();
1058                            app.waitDialog = null;
1059                        }
1060                    }
1061                }
1062            } break;
1063            case BROADCAST_INTENT_MSG: {
1064                if (DEBUG_BROADCAST) Log.v(
1065                        TAG, "Received BROADCAST_INTENT_MSG");
1066                processNextBroadcast(true);
1067            } break;
1068            case BROADCAST_TIMEOUT_MSG: {
1069                if (mDidDexOpt) {
1070                    mDidDexOpt = false;
1071                    Message nmsg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG);
1072                    mHandler.sendMessageDelayed(nmsg, BROADCAST_TIMEOUT);
1073                    return;
1074                }
1075                broadcastTimeout();
1076            } break;
1077            case PAUSE_TIMEOUT_MSG: {
1078                IBinder token = (IBinder)msg.obj;
1079                // We don't at this point know if the activity is fullscreen,
1080                // so we need to be conservative and assume it isn't.
1081                Log.w(TAG, "Activity pause timeout for " + token);
1082                activityPaused(token, null, true);
1083            } break;
1084            case IDLE_TIMEOUT_MSG: {
1085                if (mDidDexOpt) {
1086                    mDidDexOpt = false;
1087                    Message nmsg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG);
1088                    nmsg.obj = msg.obj;
1089                    mHandler.sendMessageDelayed(nmsg, IDLE_TIMEOUT);
1090                    return;
1091                }
1092                // We don't at this point know if the activity is fullscreen,
1093                // so we need to be conservative and assume it isn't.
1094                IBinder token = (IBinder)msg.obj;
1095                Log.w(TAG, "Activity idle timeout for " + token);
1096                activityIdleInternal(token, true);
1097            } break;
1098            case DESTROY_TIMEOUT_MSG: {
1099                IBinder token = (IBinder)msg.obj;
1100                // We don't at this point know if the activity is fullscreen,
1101                // so we need to be conservative and assume it isn't.
1102                Log.w(TAG, "Activity destroy timeout for " + token);
1103                activityDestroyed(token);
1104            } break;
1105            case IDLE_NOW_MSG: {
1106                IBinder token = (IBinder)msg.obj;
1107                activityIdle(token);
1108            } break;
1109            case SERVICE_TIMEOUT_MSG: {
1110                if (mDidDexOpt) {
1111                    mDidDexOpt = false;
1112                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1113                    nmsg.obj = msg.obj;
1114                    mHandler.sendMessageDelayed(nmsg, SERVICE_TIMEOUT);
1115                    return;
1116                }
1117                serviceTimeout((ProcessRecord)msg.obj);
1118            } break;
1119            case UPDATE_TIME_ZONE: {
1120                synchronized (ActivityManagerService.this) {
1121                    for (int i = mLRUProcesses.size() - 1 ; i >= 0 ; i--) {
1122                        ProcessRecord r = mLRUProcesses.get(i);
1123                        if (r.thread != null) {
1124                            try {
1125                                r.thread.updateTimeZone();
1126                            } catch (RemoteException ex) {
1127                                Log.w(TAG, "Failed to update time zone for: " + r.info.processName);
1128                            }
1129                        }
1130                    }
1131                }
1132            } break;
1133            case SHOW_UID_ERROR_MSG: {
1134                // XXX This is a temporary dialog, no need to localize.
1135                AlertDialog d = new BaseErrorDialog(mContext);
1136                d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1137                d.setCancelable(false);
1138                d.setTitle("System UIDs Inconsistent");
1139                d.setMessage("UIDs on the system are inconsistent, you need to wipe your data partition or your device will be unstable.");
1140                d.setButton("I'm Feeling Lucky",
1141                        mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1142                mUidAlert = d;
1143                d.show();
1144            } break;
1145            case IM_FEELING_LUCKY_MSG: {
1146                if (mUidAlert != null) {
1147                    mUidAlert.dismiss();
1148                    mUidAlert = null;
1149                }
1150            } break;
1151            case LAUNCH_TIMEOUT_MSG: {
1152                if (mDidDexOpt) {
1153                    mDidDexOpt = false;
1154                    Message nmsg = mHandler.obtainMessage(LAUNCH_TIMEOUT_MSG);
1155                    mHandler.sendMessageDelayed(nmsg, LAUNCH_TIMEOUT);
1156                    return;
1157                }
1158                synchronized (ActivityManagerService.this) {
1159                    if (mLaunchingActivity.isHeld()) {
1160                        Log.w(TAG, "Launch timeout has expired, giving up wake lock!");
1161                        mLaunchingActivity.release();
1162                    }
1163                }
1164            } break;
1165            case SERVICE_ERROR_MSG: {
1166                ServiceRecord srv = (ServiceRecord)msg.obj;
1167                // This needs to be *un*synchronized to avoid deadlock.
1168                Checkin.logEvent(mContext.getContentResolver(),
1169                        Checkin.Events.Tag.SYSTEM_SERVICE_LOOPING,
1170                        srv.name.toShortString());
1171            } break;
1172            case RESUME_TOP_ACTIVITY_MSG: {
1173                synchronized (ActivityManagerService.this) {
1174                    resumeTopActivityLocked(null);
1175                }
1176            } break;
1177            case PROC_START_TIMEOUT_MSG: {
1178                if (mDidDexOpt) {
1179                    mDidDexOpt = false;
1180                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1181                    nmsg.obj = msg.obj;
1182                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1183                    return;
1184                }
1185                ProcessRecord app = (ProcessRecord)msg.obj;
1186                synchronized (ActivityManagerService.this) {
1187                    processStartTimedOutLocked(app);
1188                }
1189            } break;
1190            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1191                synchronized (ActivityManagerService.this) {
1192                    doPendingActivityLaunchesLocked(true);
1193                }
1194            } break;
1195            case KILL_APPLICATION_MSG: {
1196                synchronized (ActivityManagerService.this) {
1197                    int uid = msg.arg1;
1198                    boolean restart = (msg.arg2 == 1);
1199                    String pkg = (String) msg.obj;
1200                    uninstallPackageLocked(pkg, uid, restart);
1201                }
1202            } break;
1203            }
1204        }
1205    };
1206
1207    public static void setSystemProcess() {
1208        try {
1209            ActivityManagerService m = mSelf;
1210
1211            ServiceManager.addService("activity", m);
1212            ServiceManager.addService("meminfo", new MemBinder(m));
1213            if (MONITOR_CPU_USAGE) {
1214                ServiceManager.addService("cpuinfo", new CpuBinder(m));
1215            }
1216            ServiceManager.addService("activity.broadcasts", new BroadcastsBinder(m));
1217            ServiceManager.addService("activity.services", new ServicesBinder(m));
1218            ServiceManager.addService("activity.senders", new SendersBinder(m));
1219            ServiceManager.addService("activity.providers", new ProvidersBinder(m));
1220            ServiceManager.addService("permission", new PermissionController(m));
1221
1222            ApplicationInfo info =
1223                mSelf.mContext.getPackageManager().getApplicationInfo(
1224                        "android", STOCK_PM_FLAGS);
1225            mSystemThread.installSystemApplicationInfo(info);
1226
1227            synchronized (mSelf) {
1228                ProcessRecord app = mSelf.newProcessRecordLocked(
1229                        mSystemThread.getApplicationThread(), info,
1230                        info.processName);
1231                app.persistent = true;
1232                app.pid = Process.myPid();
1233                app.maxAdj = SYSTEM_ADJ;
1234                mSelf.mProcessNames.put(app.processName, app.info.uid, app);
1235                synchronized (mSelf.mPidsSelfLocked) {
1236                    mSelf.mPidsSelfLocked.put(app.pid, app);
1237                }
1238                mSelf.updateLRUListLocked(app, true);
1239            }
1240        } catch (PackageManager.NameNotFoundException e) {
1241            throw new RuntimeException(
1242                    "Unable to find android system package", e);
1243        }
1244    }
1245
1246    public void setWindowManager(WindowManagerService wm) {
1247        mWindowManager = wm;
1248    }
1249
1250    public static final Context main(int factoryTest) {
1251        AThread thr = new AThread();
1252        thr.start();
1253
1254        synchronized (thr) {
1255            while (thr.mService == null) {
1256                try {
1257                    thr.wait();
1258                } catch (InterruptedException e) {
1259                }
1260            }
1261        }
1262
1263        ActivityManagerService m = thr.mService;
1264        mSelf = m;
1265        ActivityThread at = ActivityThread.systemMain();
1266        mSystemThread = at;
1267        Context context = at.getSystemContext();
1268        m.mContext = context;
1269        m.mFactoryTest = factoryTest;
1270        PowerManager pm =
1271            (PowerManager)context.getSystemService(Context.POWER_SERVICE);
1272        m.mGoingToSleep = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Sleep");
1273        m.mLaunchingActivity = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Launch");
1274        m.mLaunchingActivity.setReferenceCounted(false);
1275
1276        m.mBatteryStatsService.publish(context);
1277        m.mUsageStatsService.publish(context);
1278
1279        synchronized (thr) {
1280            thr.mReady = true;
1281            thr.notifyAll();
1282        }
1283
1284        m.startRunning(null, null, null, null);
1285
1286        return context;
1287    }
1288
1289    public static ActivityManagerService self() {
1290        return mSelf;
1291    }
1292
1293    static class AThread extends Thread {
1294        ActivityManagerService mService;
1295        boolean mReady = false;
1296
1297        public AThread() {
1298            super("ActivityManager");
1299        }
1300
1301        public void run() {
1302            Looper.prepare();
1303
1304            android.os.Process.setThreadPriority(
1305                    android.os.Process.THREAD_PRIORITY_FOREGROUND);
1306
1307            ActivityManagerService m = new ActivityManagerService();
1308
1309            synchronized (this) {
1310                mService = m;
1311                notifyAll();
1312            }
1313
1314            synchronized (this) {
1315                while (!mReady) {
1316                    try {
1317                        wait();
1318                    } catch (InterruptedException e) {
1319                    }
1320                }
1321            }
1322
1323            Looper.loop();
1324        }
1325    }
1326
1327    static class BroadcastsBinder extends Binder {
1328        ActivityManagerService mActivityManagerService;
1329        BroadcastsBinder(ActivityManagerService activityManagerService) {
1330            mActivityManagerService = activityManagerService;
1331        }
1332
1333        @Override
1334        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1335            mActivityManagerService.dumpBroadcasts(pw);
1336        }
1337    }
1338
1339    static class ServicesBinder extends Binder {
1340        ActivityManagerService mActivityManagerService;
1341        ServicesBinder(ActivityManagerService activityManagerService) {
1342            mActivityManagerService = activityManagerService;
1343        }
1344
1345        @Override
1346        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1347            mActivityManagerService.dumpServices(pw);
1348        }
1349    }
1350
1351    static class SendersBinder extends Binder {
1352        ActivityManagerService mActivityManagerService;
1353        SendersBinder(ActivityManagerService activityManagerService) {
1354            mActivityManagerService = activityManagerService;
1355        }
1356
1357        @Override
1358        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1359            mActivityManagerService.dumpSenders(pw);
1360        }
1361    }
1362
1363    static class ProvidersBinder extends Binder {
1364        ActivityManagerService mActivityManagerService;
1365        ProvidersBinder(ActivityManagerService activityManagerService) {
1366            mActivityManagerService = activityManagerService;
1367        }
1368
1369        @Override
1370        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1371            mActivityManagerService.dumpProviders(pw);
1372        }
1373    }
1374
1375    static class MemBinder extends Binder {
1376        ActivityManagerService mActivityManagerService;
1377        MemBinder(ActivityManagerService activityManagerService) {
1378            mActivityManagerService = activityManagerService;
1379        }
1380
1381        @Override
1382        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1383            ActivityManagerService service = mActivityManagerService;
1384            ArrayList<ProcessRecord> procs;
1385            synchronized (mActivityManagerService) {
1386                if (args != null && args.length > 0
1387                        && args[0].charAt(0) != '-') {
1388                    procs = new ArrayList<ProcessRecord>();
1389                    int pid = -1;
1390                    try {
1391                        pid = Integer.parseInt(args[0]);
1392                    } catch (NumberFormatException e) {
1393
1394                    }
1395                    for (int i=0; i<service.mLRUProcesses.size(); i++) {
1396                        ProcessRecord proc = service.mLRUProcesses.get(i);
1397                        if (proc.pid == pid) {
1398                            procs.add(proc);
1399                        } else if (proc.processName.equals(args[0])) {
1400                            procs.add(proc);
1401                        }
1402                    }
1403                    if (procs.size() <= 0) {
1404                        pw.println("No process found for: " + args[0]);
1405                        return;
1406                    }
1407                } else {
1408                    procs = service.mLRUProcesses;
1409                }
1410            }
1411            dumpApplicationMemoryUsage(fd, pw, procs, "  ", args);
1412        }
1413    }
1414
1415    static class CpuBinder extends Binder {
1416        ActivityManagerService mActivityManagerService;
1417        CpuBinder(ActivityManagerService activityManagerService) {
1418            mActivityManagerService = activityManagerService;
1419        }
1420
1421        @Override
1422        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1423            synchronized (mActivityManagerService.mProcessStatsThread) {
1424                pw.print(mActivityManagerService.mProcessStats.printCurrentState());
1425            }
1426        }
1427    }
1428
1429    private ActivityManagerService() {
1430        String v = System.getenv("ANDROID_SIMPLE_PROCESS_MANAGEMENT");
1431        if (v != null && Integer.getInteger(v) != 0) {
1432            mSimpleProcessManagement = true;
1433        }
1434        v = System.getenv("ANDROID_DEBUG_APP");
1435        if (v != null) {
1436            mSimpleProcessManagement = true;
1437        }
1438
1439        MY_PID = Process.myPid();
1440
1441        File dataDir = Environment.getDataDirectory();
1442        File systemDir = new File(dataDir, "system");
1443        systemDir.mkdirs();
1444        mBatteryStatsService = new BatteryStatsService(new File(
1445                systemDir, "batterystats.bin").toString());
1446        mBatteryStatsService.getActiveStatistics().readLocked();
1447        mBatteryStatsService.getActiveStatistics().writeLocked();
1448
1449        mUsageStatsService = new UsageStatsService( new File(
1450                systemDir, "usagestats").toString());
1451
1452        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
1453            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
1454
1455        mConfiguration.makeDefault();
1456        mProcessStats.init();
1457
1458        // Add ourself to the Watchdog monitors.
1459        Watchdog.getInstance().addMonitor(this);
1460
1461        // These values are set in system/rootdir/init.rc on startup.
1462        FOREGROUND_APP_ADJ =
1463            Integer.valueOf(SystemProperties.get("ro.FOREGROUND_APP_ADJ"));
1464        VISIBLE_APP_ADJ =
1465            Integer.valueOf(SystemProperties.get("ro.VISIBLE_APP_ADJ"));
1466        SECONDARY_SERVER_ADJ =
1467            Integer.valueOf(SystemProperties.get("ro.SECONDARY_SERVER_ADJ"));
1468        BACKUP_APP_ADJ =
1469            Integer.valueOf(SystemProperties.get("ro.BACKUP_APP_ADJ"));
1470        HOME_APP_ADJ =
1471            Integer.valueOf(SystemProperties.get("ro.HOME_APP_ADJ"));
1472        HIDDEN_APP_MIN_ADJ =
1473            Integer.valueOf(SystemProperties.get("ro.HIDDEN_APP_MIN_ADJ"));
1474        CONTENT_PROVIDER_ADJ =
1475            Integer.valueOf(SystemProperties.get("ro.CONTENT_PROVIDER_ADJ"));
1476        HIDDEN_APP_MAX_ADJ = CONTENT_PROVIDER_ADJ-1;
1477        EMPTY_APP_ADJ =
1478            Integer.valueOf(SystemProperties.get("ro.EMPTY_APP_ADJ"));
1479        FOREGROUND_APP_MEM =
1480            Integer.valueOf(SystemProperties.get("ro.FOREGROUND_APP_MEM"))*PAGE_SIZE;
1481        VISIBLE_APP_MEM =
1482            Integer.valueOf(SystemProperties.get("ro.VISIBLE_APP_MEM"))*PAGE_SIZE;
1483        SECONDARY_SERVER_MEM =
1484            Integer.valueOf(SystemProperties.get("ro.SECONDARY_SERVER_MEM"))*PAGE_SIZE;
1485        BACKUP_APP_MEM =
1486            Integer.valueOf(SystemProperties.get("ro.BACKUP_APP_MEM"))*PAGE_SIZE;
1487        HOME_APP_MEM =
1488            Integer.valueOf(SystemProperties.get("ro.HOME_APP_MEM"))*PAGE_SIZE;
1489        HIDDEN_APP_MEM =
1490            Integer.valueOf(SystemProperties.get("ro.HIDDEN_APP_MEM"))*PAGE_SIZE;
1491        EMPTY_APP_MEM =
1492            Integer.valueOf(SystemProperties.get("ro.EMPTY_APP_MEM"))*PAGE_SIZE;
1493
1494        mProcessStatsThread = new Thread("ProcessStats") {
1495            public void run() {
1496                while (true) {
1497                    try {
1498                        try {
1499                            synchronized(this) {
1500                                final long now = SystemClock.uptimeMillis();
1501                                long nextCpuDelay = (mLastCpuTime+MONITOR_CPU_MAX_TIME)-now;
1502                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
1503                                //Log.i(TAG, "Cpu delay=" + nextCpuDelay
1504                                //        + ", write delay=" + nextWriteDelay);
1505                                if (nextWriteDelay < nextCpuDelay) {
1506                                    nextCpuDelay = nextWriteDelay;
1507                                }
1508                                if (nextCpuDelay > 0) {
1509                                    this.wait(nextCpuDelay);
1510                                }
1511                            }
1512                        } catch (InterruptedException e) {
1513                        }
1514
1515                        updateCpuStatsNow();
1516                    } catch (Exception e) {
1517                        Log.e(TAG, "Unexpected exception collecting process stats", e);
1518                    }
1519                }
1520            }
1521        };
1522        mProcessStatsThread.start();
1523    }
1524
1525    @Override
1526    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
1527            throws RemoteException {
1528        try {
1529            return super.onTransact(code, data, reply, flags);
1530        } catch (RuntimeException e) {
1531            // The activity manager only throws security exceptions, so let's
1532            // log all others.
1533            if (!(e instanceof SecurityException)) {
1534                Log.e(TAG, "Activity Manager Crash", e);
1535            }
1536            throw e;
1537        }
1538    }
1539
1540    void updateCpuStats() {
1541        synchronized (mProcessStatsThread) {
1542            final long now = SystemClock.uptimeMillis();
1543            if (mLastCpuTime < (now-MONITOR_CPU_MIN_TIME)) {
1544                mProcessStatsThread.notify();
1545            }
1546        }
1547    }
1548
1549    void updateCpuStatsNow() {
1550        synchronized (mProcessStatsThread) {
1551            final long now = SystemClock.uptimeMillis();
1552            boolean haveNewCpuStats = false;
1553
1554            if (MONITOR_CPU_USAGE &&
1555                    mLastCpuTime < (now-MONITOR_CPU_MIN_TIME)) {
1556                mLastCpuTime = now;
1557                haveNewCpuStats = true;
1558                mProcessStats.update();
1559                //Log.i(TAG, mProcessStats.printCurrentState());
1560                //Log.i(TAG, "Total CPU usage: "
1561                //        + mProcessStats.getTotalCpuPercent() + "%");
1562
1563                // Log the cpu usage if the property is set.
1564                if ("true".equals(SystemProperties.get("events.cpu"))) {
1565                    int user = mProcessStats.getLastUserTime();
1566                    int system = mProcessStats.getLastSystemTime();
1567                    int iowait = mProcessStats.getLastIoWaitTime();
1568                    int irq = mProcessStats.getLastIrqTime();
1569                    int softIrq = mProcessStats.getLastSoftIrqTime();
1570                    int idle = mProcessStats.getLastIdleTime();
1571
1572                    int total = user + system + iowait + irq + softIrq + idle;
1573                    if (total == 0) total = 1;
1574
1575                    EventLog.writeEvent(LOG_CPU,
1576                            ((user+system+iowait+irq+softIrq) * 100) / total,
1577                            (user * 100) / total,
1578                            (system * 100) / total,
1579                            (iowait * 100) / total,
1580                            (irq * 100) / total,
1581                            (softIrq * 100) / total);
1582                }
1583            }
1584
1585            long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes();
1586            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
1587            synchronized(bstats) {
1588                synchronized(mPidsSelfLocked) {
1589                    if (haveNewCpuStats) {
1590                        if (mBatteryStatsService.isOnBattery()) {
1591                            final int N = mProcessStats.countWorkingStats();
1592                            for (int i=0; i<N; i++) {
1593                                ProcessStats.Stats st
1594                                        = mProcessStats.getWorkingStats(i);
1595                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
1596                                if (pr != null) {
1597                                    BatteryStatsImpl.Uid.Proc ps = pr.batteryStats;
1598                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
1599                                    ps.addSpeedStepTimes(cpuSpeedTimes);
1600                                } else {
1601                                    BatteryStatsImpl.Uid.Proc ps =
1602                                            bstats.getProcessStatsLocked(st.name, st.pid);
1603                                    if (ps != null) {
1604                                        ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
1605                                        ps.addSpeedStepTimes(cpuSpeedTimes);
1606                                    }
1607                                }
1608                            }
1609                        }
1610                    }
1611                }
1612
1613                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
1614                    mLastWriteTime = now;
1615                    mBatteryStatsService.getActiveStatistics().writeLocked();
1616                }
1617            }
1618        }
1619    }
1620
1621    /**
1622     * Initialize the application bind args. These are passed to each
1623     * process when the bindApplication() IPC is sent to the process. They're
1624     * lazily setup to make sure the services are running when they're asked for.
1625     */
1626    private HashMap<String, IBinder> getCommonServicesLocked() {
1627        if (mAppBindArgs == null) {
1628            mAppBindArgs = new HashMap<String, IBinder>();
1629
1630            // Setup the application init args
1631            mAppBindArgs.put("package", ServiceManager.getService("package"));
1632            mAppBindArgs.put("window", ServiceManager.getService("window"));
1633            mAppBindArgs.put(Context.ALARM_SERVICE,
1634                    ServiceManager.getService(Context.ALARM_SERVICE));
1635        }
1636        return mAppBindArgs;
1637    }
1638
1639    private final void setFocusedActivityLocked(HistoryRecord r) {
1640        if (mFocusedActivity != r) {
1641            mFocusedActivity = r;
1642            mWindowManager.setFocusedApp(r, true);
1643        }
1644    }
1645
1646    private final void updateLRUListLocked(ProcessRecord app,
1647            boolean oomAdj) {
1648        // put it on the LRU to keep track of when it should be exited.
1649        int lrui = mLRUProcesses.indexOf(app);
1650        if (lrui >= 0) mLRUProcesses.remove(lrui);
1651        mLRUProcesses.add(app);
1652        //Log.i(TAG, "Putting proc to front: " + app.processName);
1653        if (oomAdj) {
1654            updateOomAdjLocked();
1655        }
1656    }
1657
1658    private final boolean updateLRUListLocked(HistoryRecord r) {
1659        final boolean hadit = mLRUActivities.remove(r);
1660        mLRUActivities.add(r);
1661        return hadit;
1662    }
1663
1664    private final HistoryRecord topRunningActivityLocked(HistoryRecord notTop) {
1665        int i = mHistory.size()-1;
1666        while (i >= 0) {
1667            HistoryRecord r = (HistoryRecord)mHistory.get(i);
1668            if (!r.finishing && r != notTop) {
1669                return r;
1670            }
1671            i--;
1672        }
1673        return null;
1674    }
1675
1676    private final HistoryRecord topRunningNonDelayedActivityLocked(HistoryRecord notTop) {
1677        int i = mHistory.size()-1;
1678        while (i >= 0) {
1679            HistoryRecord r = (HistoryRecord)mHistory.get(i);
1680            if (!r.finishing && !r.delayedResume && r != notTop) {
1681                return r;
1682            }
1683            i--;
1684        }
1685        return null;
1686    }
1687
1688    /**
1689     * This is a simplified version of topRunningActivityLocked that provides a number of
1690     * optional skip-over modes.  It is intended for use with the ActivityController hook only.
1691     *
1692     * @param token If non-null, any history records matching this token will be skipped.
1693     * @param taskId If non-zero, we'll attempt to skip over records with the same task ID.
1694     *
1695     * @return Returns the HistoryRecord of the next activity on the stack.
1696     */
1697    private final HistoryRecord topRunningActivityLocked(IBinder token, int taskId) {
1698        int i = mHistory.size()-1;
1699        while (i >= 0) {
1700            HistoryRecord r = (HistoryRecord)mHistory.get(i);
1701            // Note: the taskId check depends on real taskId fields being non-zero
1702            if (!r.finishing && (token != r) && (taskId != r.task.taskId)) {
1703                return r;
1704            }
1705            i--;
1706        }
1707        return null;
1708    }
1709
1710    private final ProcessRecord getProcessRecordLocked(
1711            String processName, int uid) {
1712        if (uid == Process.SYSTEM_UID) {
1713            // The system gets to run in any process.  If there are multiple
1714            // processes with the same uid, just pick the first (this
1715            // should never happen).
1716            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(
1717                    processName);
1718            return procs != null ? procs.valueAt(0) : null;
1719        }
1720        ProcessRecord proc = mProcessNames.get(processName, uid);
1721        return proc;
1722    }
1723
1724    private void ensurePackageDexOpt(String packageName) {
1725        IPackageManager pm = ActivityThread.getPackageManager();
1726        try {
1727            if (pm.performDexOpt(packageName)) {
1728                mDidDexOpt = true;
1729            }
1730        } catch (RemoteException e) {
1731        }
1732    }
1733
1734    private boolean isNextTransitionForward() {
1735        int transit = mWindowManager.getPendingAppTransition();
1736        return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
1737                || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
1738                || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT;
1739    }
1740
1741    private final boolean realStartActivityLocked(HistoryRecord r,
1742            ProcessRecord app, boolean andResume, boolean checkConfig)
1743            throws RemoteException {
1744
1745        r.startFreezingScreenLocked(app, 0);
1746        mWindowManager.setAppVisibility(r, true);
1747
1748        // Have the window manager re-evaluate the orientation of
1749        // the screen based on the new activity order.  Note that
1750        // as a result of this, it can call back into the activity
1751        // manager with a new orientation.  We don't care about that,
1752        // because the activity is not currently running so we are
1753        // just restarting it anyway.
1754        if (checkConfig) {
1755            Configuration config = mWindowManager.updateOrientationFromAppTokens(
1756                    mConfiguration,
1757                    r.mayFreezeScreenLocked(app) ? r : null);
1758            updateConfigurationLocked(config, r);
1759        }
1760
1761        r.app = app;
1762
1763        if (localLOGV) Log.v(TAG, "Launching: " + r);
1764
1765        int idx = app.activities.indexOf(r);
1766        if (idx < 0) {
1767            app.activities.add(r);
1768        }
1769        updateLRUListLocked(app, true);
1770
1771        try {
1772            if (app.thread == null) {
1773                throw new RemoteException();
1774            }
1775            List<ResultInfo> results = null;
1776            List<Intent> newIntents = null;
1777            if (andResume) {
1778                results = r.results;
1779                newIntents = r.newIntents;
1780            }
1781            if (DEBUG_SWITCH) Log.v(TAG, "Launching: " + r
1782                    + " icicle=" + r.icicle
1783                    + " with results=" + results + " newIntents=" + newIntents
1784                    + " andResume=" + andResume);
1785            if (andResume) {
1786                EventLog.writeEvent(LOG_AM_RESTART_ACTIVITY,
1787                        System.identityHashCode(r),
1788                        r.task.taskId, r.shortComponentName);
1789            }
1790            if (r.isHomeActivity) {
1791                mHomeProcess = app;
1792            }
1793            ensurePackageDexOpt(r.intent.getComponent().getPackageName());
1794            app.thread.scheduleLaunchActivity(new Intent(r.intent), r,
1795                    System.identityHashCode(r),
1796                    r.info, r.icicle, results, newIntents, !andResume,
1797                    isNextTransitionForward());
1798        } catch (RemoteException e) {
1799            if (r.launchFailed) {
1800                // This is the second time we failed -- finish activity
1801                // and give up.
1802                Log.e(TAG, "Second failure launching "
1803                      + r.intent.getComponent().flattenToShortString()
1804                      + ", giving up", e);
1805                appDiedLocked(app, app.pid, app.thread);
1806                requestFinishActivityLocked(r, Activity.RESULT_CANCELED, null,
1807                        "2nd-crash");
1808                return false;
1809            }
1810
1811            // This is the first time we failed -- restart process and
1812            // retry.
1813            app.activities.remove(r);
1814            throw e;
1815        }
1816
1817        r.launchFailed = false;
1818        if (updateLRUListLocked(r)) {
1819            Log.w(TAG, "Activity " + r
1820                  + " being launched, but already in LRU list");
1821        }
1822
1823        if (andResume) {
1824            // As part of the process of launching, ActivityThread also performs
1825            // a resume.
1826            r.state = ActivityState.RESUMED;
1827            r.icicle = null;
1828            r.haveState = false;
1829            r.stopped = false;
1830            mResumedActivity = r;
1831            r.task.touchActiveTime();
1832            completeResumeLocked(r);
1833            pauseIfSleepingLocked();
1834        } else {
1835            // This activity is not starting in the resumed state... which
1836            // should look like we asked it to pause+stop (but remain visible),
1837            // and it has done so and reported back the current icicle and
1838            // other state.
1839            r.state = ActivityState.STOPPED;
1840            r.stopped = true;
1841        }
1842
1843        // Launch the new version setup screen if needed.  We do this -after-
1844        // launching the initial activity (that is, home), so that it can have
1845        // a chance to initialize itself while in the background, making the
1846        // switch back to it faster and look better.
1847        startSetupActivityLocked();
1848
1849        return true;
1850    }
1851
1852    private final void startSpecificActivityLocked(HistoryRecord r,
1853            boolean andResume, boolean checkConfig) {
1854        // Is this activity's application already running?
1855        ProcessRecord app = getProcessRecordLocked(r.processName,
1856                r.info.applicationInfo.uid);
1857
1858        if (r.startTime == 0) {
1859            r.startTime = SystemClock.uptimeMillis();
1860            if (mInitialStartTime == 0) {
1861                mInitialStartTime = r.startTime;
1862            }
1863        } else if (mInitialStartTime == 0) {
1864            mInitialStartTime = SystemClock.uptimeMillis();
1865        }
1866
1867        if (app != null && app.thread != null) {
1868            try {
1869                realStartActivityLocked(r, app, andResume, checkConfig);
1870                return;
1871            } catch (RemoteException e) {
1872                Log.w(TAG, "Exception when starting activity "
1873                        + r.intent.getComponent().flattenToShortString(), e);
1874            }
1875
1876            // If a dead object exception was thrown -- fall through to
1877            // restart the application.
1878        }
1879
1880        startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
1881                "activity", r.intent.getComponent(), false);
1882    }
1883
1884    private final ProcessRecord startProcessLocked(String processName,
1885            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
1886            String hostingType, ComponentName hostingName, boolean allowWhileBooting) {
1887        ProcessRecord app = getProcessRecordLocked(processName, info.uid);
1888        // We don't have to do anything more if:
1889        // (1) There is an existing application record; and
1890        // (2) The caller doesn't think it is dead, OR there is no thread
1891        //     object attached to it so we know it couldn't have crashed; and
1892        // (3) There is a pid assigned to it, so it is either starting or
1893        //     already running.
1894        if (DEBUG_PROCESSES) Log.v(TAG, "startProcess: name=" + processName
1895                + " app=" + app + " knownToBeDead=" + knownToBeDead
1896                + " thread=" + (app != null ? app.thread : null)
1897                + " pid=" + (app != null ? app.pid : -1));
1898        if (app != null &&
1899                (!knownToBeDead || app.thread == null) && app.pid > 0) {
1900            return app;
1901        }
1902
1903        String hostingNameStr = hostingName != null
1904                ? hostingName.flattenToShortString() : null;
1905
1906        if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
1907            // If we are in the background, then check to see if this process
1908            // is bad.  If so, we will just silently fail.
1909            if (mBadProcesses.get(info.processName, info.uid) != null) {
1910                return null;
1911            }
1912        } else {
1913            // When the user is explicitly starting a process, then clear its
1914            // crash count so that we won't make it bad until they see at
1915            // least one crash dialog again, and make the process good again
1916            // if it had been bad.
1917            mProcessCrashTimes.remove(info.processName, info.uid);
1918            if (mBadProcesses.get(info.processName, info.uid) != null) {
1919                EventLog.writeEvent(LOG_AM_PROCESS_GOOD, info.uid,
1920                        info.processName);
1921                mBadProcesses.remove(info.processName, info.uid);
1922                if (app != null) {
1923                    app.bad = false;
1924                }
1925            }
1926        }
1927
1928        if (app == null) {
1929            app = newProcessRecordLocked(null, info, processName);
1930            mProcessNames.put(processName, info.uid, app);
1931        } else {
1932            // If this is a new package in the process, add the package to the list
1933            app.addPackage(info.packageName);
1934        }
1935
1936        // If the system is not ready yet, then hold off on starting this
1937        // process until it is.
1938        if (!mSystemReady
1939                && !isAllowedWhileBooting(info)
1940                && !allowWhileBooting) {
1941            if (!mProcessesOnHold.contains(app)) {
1942                mProcessesOnHold.add(app);
1943            }
1944            return app;
1945        }
1946
1947        startProcessLocked(app, hostingType, hostingNameStr);
1948        return (app.pid != 0) ? app : null;
1949    }
1950
1951    boolean isAllowedWhileBooting(ApplicationInfo ai) {
1952        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
1953    }
1954
1955    private final void startProcessLocked(ProcessRecord app,
1956            String hostingType, String hostingNameStr) {
1957        if (app.pid > 0 && app.pid != MY_PID) {
1958            synchronized (mPidsSelfLocked) {
1959                mPidsSelfLocked.remove(app.pid);
1960                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
1961            }
1962            app.pid = 0;
1963        }
1964
1965        mProcessesOnHold.remove(app);
1966
1967        updateCpuStats();
1968
1969        System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1);
1970        mProcDeaths[0] = 0;
1971
1972        try {
1973            int uid = app.info.uid;
1974            int[] gids = null;
1975            try {
1976                gids = mContext.getPackageManager().getPackageGids(
1977                        app.info.packageName);
1978            } catch (PackageManager.NameNotFoundException e) {
1979                Log.w(TAG, "Unable to retrieve gids", e);
1980            }
1981            if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
1982                if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
1983                        && mTopComponent != null
1984                        && app.processName.equals(mTopComponent.getPackageName())) {
1985                    uid = 0;
1986                }
1987                if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
1988                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
1989                    uid = 0;
1990                }
1991            }
1992            int debugFlags = 0;
1993            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
1994                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
1995            }
1996            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
1997                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
1998            }
1999            if ("1".equals(SystemProperties.get("debug.assert"))) {
2000                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2001            }
2002            int pid = Process.start("android.app.ActivityThread",
2003                    mSimpleProcessManagement ? app.processName : null, uid, uid,
2004                    gids, debugFlags, null);
2005            BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
2006            synchronized (bs) {
2007                if (bs.isOnBattery()) {
2008                    app.batteryStats.incStartsLocked();
2009                }
2010            }
2011
2012            EventLog.writeEvent(LOG_AM_PROCESS_START, pid, uid,
2013                    app.processName, hostingType,
2014                    hostingNameStr != null ? hostingNameStr : "");
2015
2016            if (app.persistent) {
2017                Watchdog.getInstance().processStarted(app, app.processName, pid);
2018            }
2019
2020            StringBuilder buf = mStringBuilder;
2021            buf.setLength(0);
2022            buf.append("Start proc ");
2023            buf.append(app.processName);
2024            buf.append(" for ");
2025            buf.append(hostingType);
2026            if (hostingNameStr != null) {
2027                buf.append(" ");
2028                buf.append(hostingNameStr);
2029            }
2030            buf.append(": pid=");
2031            buf.append(pid);
2032            buf.append(" uid=");
2033            buf.append(uid);
2034            buf.append(" gids={");
2035            if (gids != null) {
2036                for (int gi=0; gi<gids.length; gi++) {
2037                    if (gi != 0) buf.append(", ");
2038                    buf.append(gids[gi]);
2039
2040                }
2041            }
2042            buf.append("}");
2043            Log.i(TAG, buf.toString());
2044            if (pid == 0 || pid == MY_PID) {
2045                // Processes are being emulated with threads.
2046                app.pid = MY_PID;
2047                app.removed = false;
2048                mStartingProcesses.add(app);
2049            } else if (pid > 0) {
2050                app.pid = pid;
2051                app.removed = false;
2052                synchronized (mPidsSelfLocked) {
2053                    this.mPidsSelfLocked.put(pid, app);
2054                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2055                    msg.obj = app;
2056                    mHandler.sendMessageDelayed(msg, PROC_START_TIMEOUT);
2057                }
2058            } else {
2059                app.pid = 0;
2060                RuntimeException e = new RuntimeException(
2061                        "Failure starting process " + app.processName
2062                        + ": returned pid=" + pid);
2063                Log.e(TAG, e.getMessage(), e);
2064            }
2065        } catch (RuntimeException e) {
2066            // XXX do better error recovery.
2067            app.pid = 0;
2068            Log.e(TAG, "Failure starting process " + app.processName, e);
2069        }
2070    }
2071
2072    private final void startPausingLocked(boolean userLeaving, boolean uiSleeping) {
2073        if (mPausingActivity != null) {
2074            RuntimeException e = new RuntimeException();
2075            Log.e(TAG, "Trying to pause when pause is already pending for "
2076                  + mPausingActivity, e);
2077        }
2078        HistoryRecord prev = mResumedActivity;
2079        if (prev == null) {
2080            RuntimeException e = new RuntimeException();
2081            Log.e(TAG, "Trying to pause when nothing is resumed", e);
2082            resumeTopActivityLocked(null);
2083            return;
2084        }
2085        if (DEBUG_PAUSE) Log.v(TAG, "Start pausing: " + prev);
2086        mResumedActivity = null;
2087        mPausingActivity = prev;
2088        mLastPausedActivity = prev;
2089        prev.state = ActivityState.PAUSING;
2090        prev.task.touchActiveTime();
2091
2092        updateCpuStats();
2093
2094        if (prev.app != null && prev.app.thread != null) {
2095            if (DEBUG_PAUSE) Log.v(TAG, "Enqueueing pending pause: " + prev);
2096            try {
2097                EventLog.writeEvent(LOG_AM_PAUSE_ACTIVITY,
2098                        System.identityHashCode(prev),
2099                        prev.shortComponentName);
2100                prev.app.thread.schedulePauseActivity(prev, prev.finishing, userLeaving,
2101                        prev.configChangeFlags);
2102                updateUsageStats(prev, false);
2103            } catch (Exception e) {
2104                // Ignore exception, if process died other code will cleanup.
2105                Log.w(TAG, "Exception thrown during pause", e);
2106                mPausingActivity = null;
2107                mLastPausedActivity = null;
2108            }
2109        } else {
2110            mPausingActivity = null;
2111            mLastPausedActivity = null;
2112        }
2113
2114        // If we are not going to sleep, we want to ensure the device is
2115        // awake until the next activity is started.
2116        if (!mSleeping && !mShuttingDown) {
2117            mLaunchingActivity.acquire();
2118            if (!mHandler.hasMessages(LAUNCH_TIMEOUT_MSG)) {
2119                // To be safe, don't allow the wake lock to be held for too long.
2120                Message msg = mHandler.obtainMessage(LAUNCH_TIMEOUT_MSG);
2121                mHandler.sendMessageDelayed(msg, LAUNCH_TIMEOUT);
2122            }
2123        }
2124
2125
2126        if (mPausingActivity != null) {
2127            // Have the window manager pause its key dispatching until the new
2128            // activity has started.  If we're pausing the activity just because
2129            // the screen is being turned off and the UI is sleeping, don't interrupt
2130            // key dispatch; the same activity will pick it up again on wakeup.
2131            if (!uiSleeping) {
2132                prev.pauseKeyDispatchingLocked();
2133            } else {
2134                if (DEBUG_PAUSE) Log.v(TAG, "Key dispatch not paused for screen off");
2135            }
2136
2137            // Schedule a pause timeout in case the app doesn't respond.
2138            // We don't give it much time because this directly impacts the
2139            // responsiveness seen by the user.
2140            Message msg = mHandler.obtainMessage(PAUSE_TIMEOUT_MSG);
2141            msg.obj = prev;
2142            mHandler.sendMessageDelayed(msg, PAUSE_TIMEOUT);
2143            if (DEBUG_PAUSE) Log.v(TAG, "Waiting for pause to complete...");
2144        } else {
2145            // This activity failed to schedule the
2146            // pause, so just treat it as being paused now.
2147            if (DEBUG_PAUSE) Log.v(TAG, "Activity not running, resuming next.");
2148            resumeTopActivityLocked(null);
2149        }
2150    }
2151
2152    private final void completePauseLocked() {
2153        HistoryRecord prev = mPausingActivity;
2154        if (DEBUG_PAUSE) Log.v(TAG, "Complete pause: " + prev);
2155
2156        if (prev != null) {
2157            if (prev.finishing) {
2158                if (DEBUG_PAUSE) Log.v(TAG, "Executing finish of activity: " + prev);
2159                prev = finishCurrentActivityLocked(prev, FINISH_AFTER_VISIBLE);
2160            } else if (prev.app != null) {
2161                if (DEBUG_PAUSE) Log.v(TAG, "Enqueueing pending stop: " + prev);
2162                if (prev.waitingVisible) {
2163                    prev.waitingVisible = false;
2164                    mWaitingVisibleActivities.remove(prev);
2165                    if (DEBUG_SWITCH || DEBUG_PAUSE) Log.v(
2166                            TAG, "Complete pause, no longer waiting: " + prev);
2167                }
2168                if (prev.configDestroy) {
2169                    // The previous is being paused because the configuration
2170                    // is changing, which means it is actually stopping...
2171                    // To juggle the fact that we are also starting a new
2172                    // instance right now, we need to first completely stop
2173                    // the current instance before starting the new one.
2174                    if (DEBUG_PAUSE) Log.v(TAG, "Destroying after pause: " + prev);
2175                    destroyActivityLocked(prev, true);
2176                } else {
2177                    mStoppingActivities.add(prev);
2178                    if (mStoppingActivities.size() > 3) {
2179                        // If we already have a few activities waiting to stop,
2180                        // then give up on things going idle and start clearing
2181                        // them out.
2182                        if (DEBUG_PAUSE) Log.v(TAG, "To many pending stops, forcing idle");
2183                        Message msg = Message.obtain();
2184                        msg.what = ActivityManagerService.IDLE_NOW_MSG;
2185                        mHandler.sendMessage(msg);
2186                    }
2187                }
2188            } else {
2189                if (DEBUG_PAUSE) Log.v(TAG, "App died during pause, not stopping: " + prev);
2190                prev = null;
2191            }
2192            mPausingActivity = null;
2193        }
2194
2195        if (!mSleeping && !mShuttingDown) {
2196            resumeTopActivityLocked(prev);
2197        } else {
2198            if (mGoingToSleep.isHeld()) {
2199                mGoingToSleep.release();
2200            }
2201            if (mShuttingDown) {
2202                notifyAll();
2203            }
2204        }
2205
2206        if (prev != null) {
2207            prev.resumeKeyDispatchingLocked();
2208        }
2209
2210        if (prev.app != null && prev.cpuTimeAtResume > 0 && mBatteryStatsService.isOnBattery()) {
2211            long diff = 0;
2212            synchronized (mProcessStatsThread) {
2213                diff = mProcessStats.getCpuTimeForPid(prev.app.pid) - prev.cpuTimeAtResume;
2214            }
2215            if (diff > 0) {
2216                BatteryStatsImpl bsi = mBatteryStatsService.getActiveStatistics();
2217                synchronized (bsi) {
2218                    BatteryStatsImpl.Uid.Proc ps =
2219                            bsi.getProcessStatsLocked(prev.info.applicationInfo.uid,
2220                            prev.info.packageName);
2221                    if (ps != null) {
2222                        ps.addForegroundTimeLocked(diff);
2223                    }
2224                }
2225            }
2226        }
2227        prev.cpuTimeAtResume = 0; // reset it
2228    }
2229
2230    /**
2231     * Once we know that we have asked an application to put an activity in
2232     * the resumed state (either by launching it or explicitly telling it),
2233     * this function updates the rest of our state to match that fact.
2234     */
2235    private final void completeResumeLocked(HistoryRecord next) {
2236        next.idle = false;
2237        next.results = null;
2238        next.newIntents = null;
2239
2240        // schedule an idle timeout in case the app doesn't do it for us.
2241        Message msg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG);
2242        msg.obj = next;
2243        mHandler.sendMessageDelayed(msg, IDLE_TIMEOUT);
2244
2245        if (false) {
2246            // The activity was never told to pause, so just keep
2247            // things going as-is.  To maintain our own state,
2248            // we need to emulate it coming back and saying it is
2249            // idle.
2250            msg = mHandler.obtainMessage(IDLE_NOW_MSG);
2251            msg.obj = next;
2252            mHandler.sendMessage(msg);
2253        }
2254
2255        reportResumedActivity(next);
2256
2257        next.thumbnail = null;
2258        setFocusedActivityLocked(next);
2259        next.resumeKeyDispatchingLocked();
2260        ensureActivitiesVisibleLocked(null, 0);
2261        mWindowManager.executeAppTransition();
2262        mNoAnimActivities.clear();
2263
2264        // Mark the point when the activity is resuming
2265        // TODO: To be more accurate, the mark should be before the onCreate,
2266        //       not after the onResume. But for subsequent starts, onResume is fine.
2267        if (next.app != null) {
2268            synchronized (mProcessStatsThread) {
2269                next.cpuTimeAtResume = mProcessStats.getCpuTimeForPid(next.app.pid);
2270            }
2271        } else {
2272            next.cpuTimeAtResume = 0; // Couldn't get the cpu time of process
2273        }
2274    }
2275
2276    /**
2277     * Make sure that all activities that need to be visible (that is, they
2278     * currently can be seen by the user) actually are.
2279     */
2280    private final void ensureActivitiesVisibleLocked(HistoryRecord top,
2281            HistoryRecord starting, String onlyThisProcess, int configChanges) {
2282        if (DEBUG_VISBILITY) Log.v(
2283                TAG, "ensureActivitiesVisible behind " + top
2284                + " configChanges=0x" + Integer.toHexString(configChanges));
2285
2286        // If the top activity is not fullscreen, then we need to
2287        // make sure any activities under it are now visible.
2288        final int count = mHistory.size();
2289        int i = count-1;
2290        while (mHistory.get(i) != top) {
2291            i--;
2292        }
2293        HistoryRecord r;
2294        boolean behindFullscreen = false;
2295        for (; i>=0; i--) {
2296            r = (HistoryRecord)mHistory.get(i);
2297            if (DEBUG_VISBILITY) Log.v(
2298                    TAG, "Make visible? " + r + " finishing=" + r.finishing
2299                    + " state=" + r.state);
2300            if (r.finishing) {
2301                continue;
2302            }
2303
2304            final boolean doThisProcess = onlyThisProcess == null
2305                    || onlyThisProcess.equals(r.processName);
2306
2307            // First: if this is not the current activity being started, make
2308            // sure it matches the current configuration.
2309            if (r != starting && doThisProcess) {
2310                ensureActivityConfigurationLocked(r, 0);
2311            }
2312
2313            if (r.app == null || r.app.thread == null) {
2314                if (onlyThisProcess == null
2315                        || onlyThisProcess.equals(r.processName)) {
2316                    // This activity needs to be visible, but isn't even
2317                    // running...  get it started, but don't resume it
2318                    // at this point.
2319                    if (DEBUG_VISBILITY) Log.v(
2320                            TAG, "Start and freeze screen for " + r);
2321                    if (r != starting) {
2322                        r.startFreezingScreenLocked(r.app, configChanges);
2323                    }
2324                    if (!r.visible) {
2325                        if (DEBUG_VISBILITY) Log.v(
2326                                TAG, "Starting and making visible: " + r);
2327                        mWindowManager.setAppVisibility(r, true);
2328                    }
2329                    if (r != starting) {
2330                        startSpecificActivityLocked(r, false, false);
2331                    }
2332                }
2333
2334            } else if (r.visible) {
2335                // If this activity is already visible, then there is nothing
2336                // else to do here.
2337                if (DEBUG_VISBILITY) Log.v(
2338                        TAG, "Skipping: already visible at " + r);
2339                r.stopFreezingScreenLocked(false);
2340
2341            } else if (onlyThisProcess == null) {
2342                // This activity is not currently visible, but is running.
2343                // Tell it to become visible.
2344                r.visible = true;
2345                if (r.state != ActivityState.RESUMED && r != starting) {
2346                    // If this activity is paused, tell it
2347                    // to now show its window.
2348                    if (DEBUG_VISBILITY) Log.v(
2349                            TAG, "Making visible and scheduling visibility: " + r);
2350                    try {
2351                        mWindowManager.setAppVisibility(r, true);
2352                        r.app.thread.scheduleWindowVisibility(r, true);
2353                        r.stopFreezingScreenLocked(false);
2354                    } catch (Exception e) {
2355                        // Just skip on any failure; we'll make it
2356                        // visible when it next restarts.
2357                        Log.w(TAG, "Exception thrown making visibile: "
2358                                + r.intent.getComponent(), e);
2359                    }
2360                }
2361            }
2362
2363            // Aggregate current change flags.
2364            configChanges |= r.configChangeFlags;
2365
2366            if (r.fullscreen) {
2367                // At this point, nothing else needs to be shown
2368                if (DEBUG_VISBILITY) Log.v(
2369                        TAG, "Stopping: fullscreen at " + r);
2370                behindFullscreen = true;
2371                i--;
2372                break;
2373            }
2374        }
2375
2376        // Now for any activities that aren't visible to the user, make
2377        // sure they no longer are keeping the screen frozen.
2378        while (i >= 0) {
2379            r = (HistoryRecord)mHistory.get(i);
2380            if (DEBUG_VISBILITY) Log.v(
2381                    TAG, "Make invisible? " + r + " finishing=" + r.finishing
2382                    + " state=" + r.state
2383                    + " behindFullscreen=" + behindFullscreen);
2384            if (!r.finishing) {
2385                if (behindFullscreen) {
2386                    if (r.visible) {
2387                        if (DEBUG_VISBILITY) Log.v(
2388                                TAG, "Making invisible: " + r);
2389                        r.visible = false;
2390                        try {
2391                            mWindowManager.setAppVisibility(r, false);
2392                            if ((r.state == ActivityState.STOPPING
2393                                    || r.state == ActivityState.STOPPED)
2394                                    && r.app != null && r.app.thread != null) {
2395                                if (DEBUG_VISBILITY) Log.v(
2396                                        TAG, "Scheduling invisibility: " + r);
2397                                r.app.thread.scheduleWindowVisibility(r, false);
2398                            }
2399                        } catch (Exception e) {
2400                            // Just skip on any failure; we'll make it
2401                            // visible when it next restarts.
2402                            Log.w(TAG, "Exception thrown making hidden: "
2403                                    + r.intent.getComponent(), e);
2404                        }
2405                    } else {
2406                        if (DEBUG_VISBILITY) Log.v(
2407                                TAG, "Already invisible: " + r);
2408                    }
2409                } else if (r.fullscreen) {
2410                    if (DEBUG_VISBILITY) Log.v(
2411                            TAG, "Now behindFullscreen: " + r);
2412                    behindFullscreen = true;
2413                }
2414            }
2415            i--;
2416        }
2417    }
2418
2419    /**
2420     * Version of ensureActivitiesVisible that can easily be called anywhere.
2421     */
2422    private final void ensureActivitiesVisibleLocked(HistoryRecord starting,
2423            int configChanges) {
2424        HistoryRecord r = topRunningActivityLocked(null);
2425        if (r != null) {
2426            ensureActivitiesVisibleLocked(r, starting, null, configChanges);
2427        }
2428    }
2429
2430    private void updateUsageStats(HistoryRecord resumedComponent, boolean resumed) {
2431        if (resumed) {
2432            mUsageStatsService.noteResumeComponent(resumedComponent.realActivity);
2433        } else {
2434            mUsageStatsService.notePauseComponent(resumedComponent.realActivity);
2435        }
2436    }
2437
2438    private boolean startHomeActivityLocked() {
2439        if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2440                && mTopAction == null) {
2441            // We are running in factory test mode, but unable to find
2442            // the factory test app, so just sit around displaying the
2443            // error message and don't try to start anything.
2444            return false;
2445        }
2446        Intent intent = new Intent(
2447            mTopAction,
2448            mTopData != null ? Uri.parse(mTopData) : null);
2449        intent.setComponent(mTopComponent);
2450        if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
2451            intent.addCategory(Intent.CATEGORY_HOME);
2452        }
2453        ActivityInfo aInfo =
2454            intent.resolveActivityInfo(mContext.getPackageManager(),
2455                    STOCK_PM_FLAGS);
2456        if (aInfo != null) {
2457            intent.setComponent(new ComponentName(
2458                    aInfo.applicationInfo.packageName, aInfo.name));
2459            // Don't do this if the home app is currently being
2460            // instrumented.
2461            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2462                    aInfo.applicationInfo.uid);
2463            if (app == null || app.instrumentationClass == null) {
2464                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
2465                startActivityLocked(null, intent, null, null, 0, aInfo,
2466                        null, null, 0, 0, 0, false, false);
2467            }
2468        }
2469
2470
2471        return true;
2472    }
2473
2474    /**
2475     * Starts the "new version setup screen" if appropriate.
2476     */
2477    private void startSetupActivityLocked() {
2478        // Only do this once per boot.
2479        if (mCheckedForSetup) {
2480            return;
2481        }
2482
2483        // We will show this screen if the current one is a different
2484        // version than the last one shown, and we are not running in
2485        // low-level factory test mode.
2486        final ContentResolver resolver = mContext.getContentResolver();
2487        if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL &&
2488                Settings.Secure.getInt(resolver,
2489                        Settings.Secure.DEVICE_PROVISIONED, 0) != 0) {
2490            mCheckedForSetup = true;
2491
2492            // See if we should be showing the platform update setup UI.
2493            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
2494            List<ResolveInfo> ris = mSelf.mContext.getPackageManager()
2495                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
2496
2497            // We don't allow third party apps to replace this.
2498            ResolveInfo ri = null;
2499            for (int i=0; ris != null && i<ris.size(); i++) {
2500                if ((ris.get(i).activityInfo.applicationInfo.flags
2501                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
2502                    ri = ris.get(i);
2503                    break;
2504                }
2505            }
2506
2507            if (ri != null) {
2508                String vers = ri.activityInfo.metaData != null
2509                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2510                        : null;
2511                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2512                    vers = ri.activityInfo.applicationInfo.metaData.getString(
2513                            Intent.METADATA_SETUP_VERSION);
2514                }
2515                String lastVers = Settings.Secure.getString(
2516                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
2517                if (vers != null && !vers.equals(lastVers)) {
2518                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2519                    intent.setComponent(new ComponentName(
2520                            ri.activityInfo.packageName, ri.activityInfo.name));
2521                    startActivityLocked(null, intent, null, null, 0, ri.activityInfo,
2522                            null, null, 0, 0, 0, false, false);
2523                }
2524            }
2525        }
2526    }
2527
2528    private void reportResumedActivity(HistoryRecord r) {
2529        //Log.i(TAG, "**** REPORT RESUME: " + r);
2530
2531        final int identHash = System.identityHashCode(r);
2532        updateUsageStats(r, true);
2533
2534        int i = mWatchers.beginBroadcast();
2535        while (i > 0) {
2536            i--;
2537            IActivityWatcher w = mWatchers.getBroadcastItem(i);
2538            if (w != null) {
2539                try {
2540                    w.activityResuming(identHash);
2541                } catch (RemoteException e) {
2542                }
2543            }
2544        }
2545        mWatchers.finishBroadcast();
2546    }
2547
2548    /**
2549     * Ensure that the top activity in the stack is resumed.
2550     *
2551     * @param prev The previously resumed activity, for when in the process
2552     * of pausing; can be null to call from elsewhere.
2553     *
2554     * @return Returns true if something is being resumed, or false if
2555     * nothing happened.
2556     */
2557    private final boolean resumeTopActivityLocked(HistoryRecord prev) {
2558        // Find the first activity that is not finishing.
2559        HistoryRecord next = topRunningActivityLocked(null);
2560
2561        // Remember how we'll process this pause/resume situation, and ensure
2562        // that the state is reset however we wind up proceeding.
2563        final boolean userLeaving = mUserLeaving;
2564        mUserLeaving = false;
2565
2566        if (next == null) {
2567            // There are no more activities!  Let's just start up the
2568            // Launcher...
2569            return startHomeActivityLocked();
2570        }
2571
2572        next.delayedResume = false;
2573
2574        // If the top activity is the resumed one, nothing to do.
2575        if (mResumedActivity == next && next.state == ActivityState.RESUMED) {
2576            // Make sure we have executed any pending transitions, since there
2577            // should be nothing left to do at this point.
2578            mWindowManager.executeAppTransition();
2579            mNoAnimActivities.clear();
2580            return false;
2581        }
2582
2583        // If we are sleeping, and there is no resumed activity, and the top
2584        // activity is paused, well that is the state we want.
2585        if ((mSleeping || mShuttingDown)
2586                && mLastPausedActivity == next && next.state == ActivityState.PAUSED) {
2587            // Make sure we have executed any pending transitions, since there
2588            // should be nothing left to do at this point.
2589            mWindowManager.executeAppTransition();
2590            mNoAnimActivities.clear();
2591            return false;
2592        }
2593
2594        // The activity may be waiting for stop, but that is no longer
2595        // appropriate for it.
2596        mStoppingActivities.remove(next);
2597        mWaitingVisibleActivities.remove(next);
2598
2599        if (DEBUG_SWITCH) Log.v(TAG, "Resuming " + next);
2600
2601        // If we are currently pausing an activity, then don't do anything
2602        // until that is done.
2603        if (mPausingActivity != null) {
2604            if (DEBUG_SWITCH) Log.v(TAG, "Skip resume: pausing=" + mPausingActivity);
2605            return false;
2606        }
2607
2608        // We need to start pausing the current activity so the top one
2609        // can be resumed...
2610        if (mResumedActivity != null) {
2611            if (DEBUG_SWITCH) Log.v(TAG, "Skip resume: need to start pausing");
2612            startPausingLocked(userLeaving, false);
2613            return true;
2614        }
2615
2616        if (prev != null && prev != next) {
2617            if (!prev.waitingVisible && next != null && !next.nowVisible) {
2618                prev.waitingVisible = true;
2619                mWaitingVisibleActivities.add(prev);
2620                if (DEBUG_SWITCH) Log.v(
2621                        TAG, "Resuming top, waiting visible to hide: " + prev);
2622            } else {
2623                // The next activity is already visible, so hide the previous
2624                // activity's windows right now so we can show the new one ASAP.
2625                // We only do this if the previous is finishing, which should mean
2626                // it is on top of the one being resumed so hiding it quickly
2627                // is good.  Otherwise, we want to do the normal route of allowing
2628                // the resumed activity to be shown so we can decide if the
2629                // previous should actually be hidden depending on whether the
2630                // new one is found to be full-screen or not.
2631                if (prev.finishing) {
2632                    mWindowManager.setAppVisibility(prev, false);
2633                    if (DEBUG_SWITCH) Log.v(TAG, "Not waiting for visible to hide: "
2634                            + prev + ", waitingVisible="
2635                            + (prev != null ? prev.waitingVisible : null)
2636                            + ", nowVisible=" + next.nowVisible);
2637                } else {
2638                    if (DEBUG_SWITCH) Log.v(TAG, "Previous already visible but still waiting to hide: "
2639                        + prev + ", waitingVisible="
2640                        + (prev != null ? prev.waitingVisible : null)
2641                        + ", nowVisible=" + next.nowVisible);
2642                }
2643            }
2644        }
2645
2646        // We are starting up the next activity, so tell the window manager
2647        // that the previous one will be hidden soon.  This way it can know
2648        // to ignore it when computing the desired screen orientation.
2649        if (prev != null) {
2650            if (prev.finishing) {
2651                if (DEBUG_TRANSITION) Log.v(TAG,
2652                        "Prepare close transition: prev=" + prev);
2653                if (mNoAnimActivities.contains(prev)) {
2654                    mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_NONE);
2655                } else {
2656                    mWindowManager.prepareAppTransition(prev.task == next.task
2657                            ? WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE
2658                            : WindowManagerPolicy.TRANSIT_TASK_CLOSE);
2659                }
2660                mWindowManager.setAppWillBeHidden(prev);
2661                mWindowManager.setAppVisibility(prev, false);
2662            } else {
2663                if (DEBUG_TRANSITION) Log.v(TAG,
2664                        "Prepare open transition: prev=" + prev);
2665                if (mNoAnimActivities.contains(next)) {
2666                    mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_NONE);
2667                } else {
2668                    mWindowManager.prepareAppTransition(prev.task == next.task
2669                            ? WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
2670                            : WindowManagerPolicy.TRANSIT_TASK_OPEN);
2671                }
2672            }
2673            if (false) {
2674                mWindowManager.setAppWillBeHidden(prev);
2675                mWindowManager.setAppVisibility(prev, false);
2676            }
2677        } else if (mHistory.size() > 1) {
2678            if (DEBUG_TRANSITION) Log.v(TAG,
2679                    "Prepare open transition: no previous");
2680            if (mNoAnimActivities.contains(next)) {
2681                mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_NONE);
2682            } else {
2683                mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN);
2684            }
2685        }
2686
2687        if (next.app != null && next.app.thread != null) {
2688            if (DEBUG_SWITCH) Log.v(TAG, "Resume running: " + next);
2689
2690            // This activity is now becoming visible.
2691            mWindowManager.setAppVisibility(next, true);
2692
2693            HistoryRecord lastResumedActivity = mResumedActivity;
2694            ActivityState lastState = next.state;
2695
2696            updateCpuStats();
2697
2698            next.state = ActivityState.RESUMED;
2699            mResumedActivity = next;
2700            next.task.touchActiveTime();
2701            updateLRUListLocked(next.app, true);
2702            updateLRUListLocked(next);
2703
2704            // Have the window manager re-evaluate the orientation of
2705            // the screen based on the new activity order.
2706            Configuration config = mWindowManager.updateOrientationFromAppTokens(
2707                    mConfiguration,
2708                    next.mayFreezeScreenLocked(next.app) ? next : null);
2709            if (config != null) {
2710                next.frozenBeforeDestroy = true;
2711            }
2712            if (!updateConfigurationLocked(config, next)) {
2713                // The configuration update wasn't able to keep the existing
2714                // instance of the activity, and instead started a new one.
2715                // We should be all done, but let's just make sure our activity
2716                // is still at the top and schedule another run if something
2717                // weird happened.
2718                HistoryRecord nextNext = topRunningActivityLocked(null);
2719                if (DEBUG_SWITCH) Log.i(TAG,
2720                        "Activity config changed during resume: " + next
2721                        + ", new next: " + nextNext);
2722                if (nextNext != next) {
2723                    // Do over!
2724                    mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG);
2725                }
2726                setFocusedActivityLocked(next);
2727                ensureActivitiesVisibleLocked(null, 0);
2728                mWindowManager.executeAppTransition();
2729                mNoAnimActivities.clear();
2730                return true;
2731            }
2732
2733            try {
2734                // Deliver all pending results.
2735                ArrayList a = next.results;
2736                if (a != null) {
2737                    final int N = a.size();
2738                    if (!next.finishing && N > 0) {
2739                        if (DEBUG_RESULTS) Log.v(
2740                                TAG, "Delivering results to " + next
2741                                + ": " + a);
2742                        next.app.thread.scheduleSendResult(next, a);
2743                    }
2744                }
2745
2746                if (next.newIntents != null) {
2747                    next.app.thread.scheduleNewIntent(next.newIntents, next);
2748                }
2749
2750                EventLog.writeEvent(LOG_AM_RESUME_ACTIVITY,
2751                        System.identityHashCode(next),
2752                        next.task.taskId, next.shortComponentName);
2753
2754                next.app.thread.scheduleResumeActivity(next,
2755                        isNextTransitionForward());
2756
2757                pauseIfSleepingLocked();
2758
2759            } catch (Exception e) {
2760                // Whoops, need to restart this activity!
2761                next.state = lastState;
2762                mResumedActivity = lastResumedActivity;
2763                if (Config.LOGD) Log.d(TAG,
2764                        "Restarting because process died: " + next);
2765                if (!next.hasBeenLaunched) {
2766                    next.hasBeenLaunched = true;
2767                } else {
2768                    if (SHOW_APP_STARTING_ICON) {
2769                        mWindowManager.setAppStartingWindow(
2770                                next, next.packageName, next.theme,
2771                                next.nonLocalizedLabel,
2772                                next.labelRes, next.icon, null, true);
2773                    }
2774                }
2775                startSpecificActivityLocked(next, true, false);
2776                return true;
2777            }
2778
2779            // From this point on, if something goes wrong there is no way
2780            // to recover the activity.
2781            try {
2782                next.visible = true;
2783                completeResumeLocked(next);
2784            } catch (Exception e) {
2785                // If any exception gets thrown, toss away this
2786                // activity and try the next one.
2787                Log.w(TAG, "Exception thrown during resume of " + next, e);
2788                requestFinishActivityLocked(next, Activity.RESULT_CANCELED, null,
2789                        "resume-exception");
2790                return true;
2791            }
2792
2793            // Didn't need to use the icicle, and it is now out of date.
2794            next.icicle = null;
2795            next.haveState = false;
2796            next.stopped = false;
2797
2798        } else {
2799            // Whoops, need to restart this activity!
2800            if (!next.hasBeenLaunched) {
2801                next.hasBeenLaunched = true;
2802            } else {
2803                if (SHOW_APP_STARTING_ICON) {
2804                    mWindowManager.setAppStartingWindow(
2805                            next, next.packageName, next.theme,
2806                            next.nonLocalizedLabel,
2807                            next.labelRes, next.icon, null, true);
2808                }
2809                if (DEBUG_SWITCH) Log.v(TAG, "Restarting: " + next);
2810            }
2811            startSpecificActivityLocked(next, true, true);
2812        }
2813
2814        return true;
2815    }
2816
2817    private final void startActivityLocked(HistoryRecord r, boolean newTask,
2818            boolean doResume) {
2819        final int NH = mHistory.size();
2820
2821        int addPos = -1;
2822
2823        if (!newTask) {
2824            // If starting in an existing task, find where that is...
2825            HistoryRecord next = null;
2826            boolean startIt = true;
2827            for (int i = NH-1; i >= 0; i--) {
2828                HistoryRecord p = (HistoryRecord)mHistory.get(i);
2829                if (p.finishing) {
2830                    continue;
2831                }
2832                if (p.task == r.task) {
2833                    // Here it is!  Now, if this is not yet visible to the
2834                    // user, then just add it without starting; it will
2835                    // get started when the user navigates back to it.
2836                    addPos = i+1;
2837                    if (!startIt) {
2838                        mHistory.add(addPos, r);
2839                        r.inHistory = true;
2840                        r.task.numActivities++;
2841                        mWindowManager.addAppToken(addPos, r, r.task.taskId,
2842                                r.info.screenOrientation, r.fullscreen);
2843                        if (VALIDATE_TOKENS) {
2844                            mWindowManager.validateAppTokens(mHistory);
2845                        }
2846                        return;
2847                    }
2848                    break;
2849                }
2850                if (p.fullscreen) {
2851                    startIt = false;
2852                }
2853                next = p;
2854            }
2855        }
2856
2857        // Place a new activity at top of stack, so it is next to interact
2858        // with the user.
2859        if (addPos < 0) {
2860            addPos = mHistory.size();
2861        }
2862
2863        // If we are not placing the new activity frontmost, we do not want
2864        // to deliver the onUserLeaving callback to the actual frontmost
2865        // activity
2866        if (addPos < NH) {
2867            mUserLeaving = false;
2868            if (DEBUG_USER_LEAVING) Log.v(TAG, "startActivity() behind front, mUserLeaving=false");
2869        }
2870
2871        // Slot the activity into the history stack and proceed
2872        mHistory.add(addPos, r);
2873        r.inHistory = true;
2874        r.frontOfTask = newTask;
2875        r.task.numActivities++;
2876        if (NH > 0) {
2877            // We want to show the starting preview window if we are
2878            // switching to a new task, or the next activity's process is
2879            // not currently running.
2880            boolean showStartingIcon = newTask;
2881            ProcessRecord proc = r.app;
2882            if (proc == null) {
2883                proc = mProcessNames.get(r.processName, r.info.applicationInfo.uid);
2884            }
2885            if (proc == null || proc.thread == null) {
2886                showStartingIcon = true;
2887            }
2888            if (DEBUG_TRANSITION) Log.v(TAG,
2889                    "Prepare open transition: starting " + r);
2890            if ((r.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) {
2891                mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_NONE);
2892                mNoAnimActivities.add(r);
2893            } else if ((r.intent.getFlags()&Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0) {
2894                mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_TASK_OPEN);
2895                mNoAnimActivities.remove(r);
2896            } else {
2897                mWindowManager.prepareAppTransition(newTask
2898                        ? WindowManagerPolicy.TRANSIT_TASK_OPEN
2899                        : WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN);
2900                mNoAnimActivities.remove(r);
2901            }
2902            mWindowManager.addAppToken(
2903                    addPos, r, r.task.taskId, r.info.screenOrientation, r.fullscreen);
2904            boolean doShow = true;
2905            if (newTask) {
2906                // Even though this activity is starting fresh, we still need
2907                // to reset it to make sure we apply affinities to move any
2908                // existing activities from other tasks in to it.
2909                // If the caller has requested that the target task be
2910                // reset, then do so.
2911                if ((r.intent.getFlags()
2912                        &Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
2913                    resetTaskIfNeededLocked(r, r);
2914                    doShow = topRunningNonDelayedActivityLocked(null) == r;
2915                }
2916            }
2917            if (SHOW_APP_STARTING_ICON && doShow) {
2918                // Figure out if we are transitioning from another activity that is
2919                // "has the same starting icon" as the next one.  This allows the
2920                // window manager to keep the previous window it had previously
2921                // created, if it still had one.
2922                HistoryRecord prev = mResumedActivity;
2923                if (prev != null) {
2924                    // We don't want to reuse the previous starting preview if:
2925                    // (1) The current activity is in a different task.
2926                    if (prev.task != r.task) prev = null;
2927                    // (2) The current activity is already displayed.
2928                    else if (prev.nowVisible) prev = null;
2929                }
2930                mWindowManager.setAppStartingWindow(
2931                        r, r.packageName, r.theme, r.nonLocalizedLabel,
2932                        r.labelRes, r.icon, prev, showStartingIcon);
2933            }
2934        } else {
2935            // If this is the first activity, don't do any fancy animations,
2936            // because there is nothing for it to animate on top of.
2937            mWindowManager.addAppToken(addPos, r, r.task.taskId,
2938                    r.info.screenOrientation, r.fullscreen);
2939        }
2940        if (VALIDATE_TOKENS) {
2941            mWindowManager.validateAppTokens(mHistory);
2942        }
2943
2944        if (doResume) {
2945            resumeTopActivityLocked(null);
2946        }
2947    }
2948
2949    /**
2950     * Perform clear operation as requested by
2951     * {@link Intent#FLAG_ACTIVITY_CLEAR_TOP}: search from the top of the
2952     * stack to the given task, then look for
2953     * an instance of that activity in the stack and, if found, finish all
2954     * activities on top of it and return the instance.
2955     *
2956     * @param newR Description of the new activity being started.
2957     * @return Returns the old activity that should be continue to be used,
2958     * or null if none was found.
2959     */
2960    private final HistoryRecord performClearTaskLocked(int taskId,
2961            HistoryRecord newR, int launchFlags, boolean doClear) {
2962        int i = mHistory.size();
2963
2964        // First find the requested task.
2965        while (i > 0) {
2966            i--;
2967            HistoryRecord r = (HistoryRecord)mHistory.get(i);
2968            if (r.task.taskId == taskId) {
2969                i++;
2970                break;
2971            }
2972        }
2973
2974        // Now clear it.
2975        while (i > 0) {
2976            i--;
2977            HistoryRecord r = (HistoryRecord)mHistory.get(i);
2978            if (r.finishing) {
2979                continue;
2980            }
2981            if (r.task.taskId != taskId) {
2982                return null;
2983            }
2984            if (r.realActivity.equals(newR.realActivity)) {
2985                // Here it is!  Now finish everything in front...
2986                HistoryRecord ret = r;
2987                if (doClear) {
2988                    while (i < (mHistory.size()-1)) {
2989                        i++;
2990                        r = (HistoryRecord)mHistory.get(i);
2991                        if (r.finishing) {
2992                            continue;
2993                        }
2994                        if (finishActivityLocked(r, i, Activity.RESULT_CANCELED,
2995                                null, "clear")) {
2996                            i--;
2997                        }
2998                    }
2999                }
3000
3001                // Finally, if this is a normal launch mode (that is, not
3002                // expecting onNewIntent()), then we will finish the current
3003                // instance of the activity so a new fresh one can be started.
3004                if (ret.launchMode == ActivityInfo.LAUNCH_MULTIPLE
3005                        && (launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) == 0) {
3006                    if (!ret.finishing) {
3007                        int index = indexOfTokenLocked(ret);
3008                        if (index >= 0) {
3009                            finishActivityLocked(ret, 0, Activity.RESULT_CANCELED,
3010                                    null, "clear");
3011                        }
3012                        return null;
3013                    }
3014                }
3015
3016                return ret;
3017            }
3018        }
3019
3020        return null;
3021    }
3022
3023    /**
3024     * Find the activity in the history stack within the given task.  Returns
3025     * the index within the history at which it's found, or < 0 if not found.
3026     */
3027    private final int findActivityInHistoryLocked(HistoryRecord r, int task) {
3028        int i = mHistory.size();
3029        while (i > 0) {
3030            i--;
3031            HistoryRecord candidate = (HistoryRecord)mHistory.get(i);
3032            if (candidate.task.taskId != task) {
3033                break;
3034            }
3035            if (candidate.realActivity.equals(r.realActivity)) {
3036                return i;
3037            }
3038        }
3039
3040        return -1;
3041    }
3042
3043    /**
3044     * Reorder the history stack so that the activity at the given index is
3045     * brought to the front.
3046     */
3047    private final HistoryRecord moveActivityToFrontLocked(int where) {
3048        HistoryRecord newTop = (HistoryRecord)mHistory.remove(where);
3049        int top = mHistory.size();
3050        HistoryRecord oldTop = (HistoryRecord)mHistory.get(top-1);
3051        mHistory.add(top, newTop);
3052        oldTop.frontOfTask = false;
3053        newTop.frontOfTask = true;
3054        return newTop;
3055    }
3056
3057    /**
3058     * Deliver a new Intent to an existing activity, so that its onNewIntent()
3059     * method will be called at the proper time.
3060     */
3061    private final void deliverNewIntentLocked(HistoryRecord r, Intent intent) {
3062        boolean sent = false;
3063        if (r.state == ActivityState.RESUMED
3064                && r.app != null && r.app.thread != null) {
3065            try {
3066                ArrayList<Intent> ar = new ArrayList<Intent>();
3067                ar.add(new Intent(intent));
3068                r.app.thread.scheduleNewIntent(ar, r);
3069                sent = true;
3070            } catch (Exception e) {
3071                Log.w(TAG, "Exception thrown sending new intent to " + r, e);
3072            }
3073        }
3074        if (!sent) {
3075            r.addNewIntentLocked(new Intent(intent));
3076        }
3077    }
3078
3079    private final void logStartActivity(int tag, HistoryRecord r,
3080            TaskRecord task) {
3081        EventLog.writeEvent(tag,
3082                System.identityHashCode(r), task.taskId,
3083                r.shortComponentName, r.intent.getAction(),
3084                r.intent.getType(), r.intent.getDataString(),
3085                r.intent.getFlags());
3086    }
3087
3088    private final int startActivityLocked(IApplicationThread caller,
3089            Intent intent, String resolvedType,
3090            Uri[] grantedUriPermissions,
3091            int grantedMode, ActivityInfo aInfo, IBinder resultTo,
3092            String resultWho, int requestCode,
3093            int callingPid, int callingUid, boolean onlyIfNeeded,
3094            boolean componentSpecified) {
3095        Log.i(TAG, "Starting activity: " + intent);
3096
3097        HistoryRecord sourceRecord = null;
3098        HistoryRecord resultRecord = null;
3099        if (resultTo != null) {
3100            int index = indexOfTokenLocked(resultTo);
3101            if (DEBUG_RESULTS) Log.v(
3102                TAG, "Sending result to " + resultTo + " (index " + index + ")");
3103            if (index >= 0) {
3104                sourceRecord = (HistoryRecord)mHistory.get(index);
3105                if (requestCode >= 0 && !sourceRecord.finishing) {
3106                    resultRecord = sourceRecord;
3107                }
3108            }
3109        }
3110
3111        int launchFlags = intent.getFlags();
3112
3113        if ((launchFlags&Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0
3114                && sourceRecord != null) {
3115            // Transfer the result target from the source activity to the new
3116            // one being started, including any failures.
3117            if (requestCode >= 0) {
3118                return START_FORWARD_AND_REQUEST_CONFLICT;
3119            }
3120            resultRecord = sourceRecord.resultTo;
3121            resultWho = sourceRecord.resultWho;
3122            requestCode = sourceRecord.requestCode;
3123            sourceRecord.resultTo = null;
3124            if (resultRecord != null) {
3125                resultRecord.removeResultsLocked(
3126                    sourceRecord, resultWho, requestCode);
3127            }
3128        }
3129
3130        int err = START_SUCCESS;
3131
3132        if (intent.getComponent() == null) {
3133            // We couldn't find a class that can handle the given Intent.
3134            // That's the end of that!
3135            err = START_INTENT_NOT_RESOLVED;
3136        }
3137
3138        if (err == START_SUCCESS && aInfo == null) {
3139            // We couldn't find the specific class specified in the Intent.
3140            // Also the end of the line.
3141            err = START_CLASS_NOT_FOUND;
3142        }
3143
3144        ProcessRecord callerApp = null;
3145        if (err == START_SUCCESS && caller != null) {
3146            callerApp = getRecordForAppLocked(caller);
3147            if (callerApp != null) {
3148                callingPid = callerApp.pid;
3149                callingUid = callerApp.info.uid;
3150            } else {
3151                Log.w(TAG, "Unable to find app for caller " + caller
3152                      + " (pid=" + callingPid + ") when starting: "
3153                      + intent.toString());
3154                err = START_PERMISSION_DENIED;
3155            }
3156        }
3157
3158        if (err != START_SUCCESS) {
3159            if (resultRecord != null) {
3160                sendActivityResultLocked(-1,
3161                    resultRecord, resultWho, requestCode,
3162                    Activity.RESULT_CANCELED, null);
3163            }
3164            return err;
3165        }
3166
3167        final int perm = checkComponentPermission(aInfo.permission, callingPid,
3168                callingUid, aInfo.exported ? -1 : aInfo.applicationInfo.uid);
3169        if (perm != PackageManager.PERMISSION_GRANTED) {
3170            if (resultRecord != null) {
3171                sendActivityResultLocked(-1,
3172                    resultRecord, resultWho, requestCode,
3173                    Activity.RESULT_CANCELED, null);
3174            }
3175            String msg = "Permission Denial: starting " + intent.toString()
3176                    + " from " + callerApp + " (pid=" + callingPid
3177                    + ", uid=" + callingUid + ")"
3178                    + " requires " + aInfo.permission;
3179            Log.w(TAG, msg);
3180            throw new SecurityException(msg);
3181        }
3182
3183        if (mController != null) {
3184            boolean abort = false;
3185            try {
3186                // The Intent we give to the watcher has the extra data
3187                // stripped off, since it can contain private information.
3188                Intent watchIntent = intent.cloneFilter();
3189                abort = !mController.activityStarting(watchIntent,
3190                        aInfo.applicationInfo.packageName);
3191            } catch (RemoteException e) {
3192                mController = null;
3193            }
3194
3195            if (abort) {
3196                if (resultRecord != null) {
3197                    sendActivityResultLocked(-1,
3198                        resultRecord, resultWho, requestCode,
3199                        Activity.RESULT_CANCELED, null);
3200                }
3201                // We pretend to the caller that it was really started, but
3202                // they will just get a cancel result.
3203                return START_SUCCESS;
3204            }
3205        }
3206
3207        HistoryRecord r = new HistoryRecord(this, callerApp, callingUid,
3208                intent, resolvedType, aInfo, mConfiguration,
3209                resultRecord, resultWho, requestCode, componentSpecified);
3210
3211        if (mResumedActivity == null
3212                || mResumedActivity.info.applicationInfo.uid != callingUid) {
3213            if (!checkAppSwitchAllowedLocked(callingPid, callingUid, "Activity start")) {
3214                PendingActivityLaunch pal = new PendingActivityLaunch();
3215                pal.r = r;
3216                pal.sourceRecord = sourceRecord;
3217                pal.grantedUriPermissions = grantedUriPermissions;
3218                pal.grantedMode = grantedMode;
3219                pal.onlyIfNeeded = onlyIfNeeded;
3220                mPendingActivityLaunches.add(pal);
3221                return START_SWITCHES_CANCELED;
3222            }
3223        }
3224
3225        if (mDidAppSwitch) {
3226            // This is the second allowed switch since we stopped switches,
3227            // so now just generally allow switches.  Use case: user presses
3228            // home (switches disabled, switch to home, mDidAppSwitch now true);
3229            // user taps a home icon (coming from home so allowed, we hit here
3230            // and now allow anyone to switch again).
3231            mAppSwitchesAllowedTime = 0;
3232        } else {
3233            mDidAppSwitch = true;
3234        }
3235
3236        doPendingActivityLaunchesLocked(false);
3237
3238        return startActivityUncheckedLocked(r, sourceRecord,
3239                grantedUriPermissions, grantedMode, onlyIfNeeded, true);
3240    }
3241
3242    private final void doPendingActivityLaunchesLocked(boolean doResume) {
3243        final int N = mPendingActivityLaunches.size();
3244        if (N <= 0) {
3245            return;
3246        }
3247        for (int i=0; i<N; i++) {
3248            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
3249            startActivityUncheckedLocked(pal.r, pal.sourceRecord,
3250                    pal.grantedUriPermissions, pal.grantedMode, pal.onlyIfNeeded,
3251                    doResume && i == (N-1));
3252        }
3253        mPendingActivityLaunches.clear();
3254    }
3255
3256    private final int startActivityUncheckedLocked(HistoryRecord r,
3257            HistoryRecord sourceRecord, Uri[] grantedUriPermissions,
3258            int grantedMode, boolean onlyIfNeeded, boolean doResume) {
3259        final Intent intent = r.intent;
3260        final int callingUid = r.launchedFromUid;
3261
3262        int launchFlags = intent.getFlags();
3263
3264        // We'll invoke onUserLeaving before onPause only if the launching
3265        // activity did not explicitly state that this is an automated launch.
3266        mUserLeaving = (launchFlags&Intent.FLAG_ACTIVITY_NO_USER_ACTION) == 0;
3267        if (DEBUG_USER_LEAVING) Log.v(TAG,
3268                "startActivity() => mUserLeaving=" + mUserLeaving);
3269
3270        // If the caller has asked not to resume at this point, we make note
3271        // of this in the record so that we can skip it when trying to find
3272        // the top running activity.
3273        if (!doResume) {
3274            r.delayedResume = true;
3275        }
3276
3277        HistoryRecord notTop = (launchFlags&Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP)
3278                != 0 ? r : null;
3279
3280        // If the onlyIfNeeded flag is set, then we can do this if the activity
3281        // being launched is the same as the one making the call...  or, as
3282        // a special case, if we do not know the caller then we count the
3283        // current top activity as the caller.
3284        if (onlyIfNeeded) {
3285            HistoryRecord checkedCaller = sourceRecord;
3286            if (checkedCaller == null) {
3287                checkedCaller = topRunningNonDelayedActivityLocked(notTop);
3288            }
3289            if (!checkedCaller.realActivity.equals(r.realActivity)) {
3290                // Caller is not the same as launcher, so always needed.
3291                onlyIfNeeded = false;
3292            }
3293        }
3294
3295        if (grantedUriPermissions != null && callingUid > 0) {
3296            for (int i=0; i<grantedUriPermissions.length; i++) {
3297                grantUriPermissionLocked(callingUid, r.packageName,
3298                        grantedUriPermissions[i], grantedMode, r);
3299            }
3300        }
3301
3302        grantUriPermissionFromIntentLocked(callingUid, r.packageName,
3303                intent, r);
3304
3305        if (sourceRecord == null) {
3306            // This activity is not being started from another...  in this
3307            // case we -always- start a new task.
3308            if ((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
3309                Log.w(TAG, "startActivity called from non-Activity context; forcing Intent.FLAG_ACTIVITY_NEW_TASK for: "
3310                      + intent);
3311                launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
3312            }
3313        } else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
3314            // The original activity who is starting us is running as a single
3315            // instance...  this new activity it is starting must go on its
3316            // own task.
3317            launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
3318        } else if (r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE
3319                || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
3320            // The activity being started is a single instance...  it always
3321            // gets launched into its own task.
3322            launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
3323        }
3324
3325        if (r.resultTo != null && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
3326            // For whatever reason this activity is being launched into a new
3327            // task...  yet the caller has requested a result back.  Well, that
3328            // is pretty messed up, so instead immediately send back a cancel
3329            // and let the new task continue launched as normal without a
3330            // dependency on its originator.
3331            Log.w(TAG, "Activity is launching as a new task, so cancelling activity result.");
3332            sendActivityResultLocked(-1,
3333                    r.resultTo, r.resultWho, r.requestCode,
3334                Activity.RESULT_CANCELED, null);
3335            r.resultTo = null;
3336        }
3337
3338        boolean addingToTask = false;
3339        if (((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0 &&
3340                (launchFlags&Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
3341                || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
3342                || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
3343            // If bring to front is requested, and no result is requested, and
3344            // we can find a task that was started with this same
3345            // component, then instead of launching bring that one to the front.
3346            if (r.resultTo == null) {
3347                // See if there is a task to bring to the front.  If this is
3348                // a SINGLE_INSTANCE activity, there can be one and only one
3349                // instance of it in the history, and it is always in its own
3350                // unique task, so we do a special search.
3351                HistoryRecord taskTop = r.launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE
3352                        ? findTaskLocked(intent, r.info)
3353                        : findActivityLocked(intent, r.info);
3354                if (taskTop != null) {
3355                    if (taskTop.task.intent == null) {
3356                        // This task was started because of movement of
3357                        // the activity based on affinity...  now that we
3358                        // are actually launching it, we can assign the
3359                        // base intent.
3360                        taskTop.task.setIntent(intent, r.info);
3361                    }
3362                    // If the target task is not in the front, then we need
3363                    // to bring it to the front...  except...  well, with
3364                    // SINGLE_TASK_LAUNCH it's not entirely clear.  We'd like
3365                    // to have the same behavior as if a new instance was
3366                    // being started, which means not bringing it to the front
3367                    // if the caller is not itself in the front.
3368                    HistoryRecord curTop = topRunningNonDelayedActivityLocked(notTop);
3369                    if (curTop.task != taskTop.task) {
3370                        r.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
3371                        boolean callerAtFront = sourceRecord == null
3372                                || curTop.task == sourceRecord.task;
3373                        if (callerAtFront) {
3374                            // We really do want to push this one into the
3375                            // user's face, right now.
3376                            moveTaskToFrontLocked(taskTop.task, r);
3377                        }
3378                    }
3379                    // If the caller has requested that the target task be
3380                    // reset, then do so.
3381                    if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
3382                        taskTop = resetTaskIfNeededLocked(taskTop, r);
3383                    }
3384                    if (onlyIfNeeded) {
3385                        // We don't need to start a new activity, and
3386                        // the client said not to do anything if that
3387                        // is the case, so this is it!  And for paranoia, make
3388                        // sure we have correctly resumed the top activity.
3389                        if (doResume) {
3390                            resumeTopActivityLocked(null);
3391                        }
3392                        return START_RETURN_INTENT_TO_CALLER;
3393                    }
3394                    if ((launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0
3395                            || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
3396                            || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
3397                        // In this situation we want to remove all activities
3398                        // from the task up to the one being started.  In most
3399                        // cases this means we are resetting the task to its
3400                        // initial state.
3401                        HistoryRecord top = performClearTaskLocked(
3402                                taskTop.task.taskId, r, launchFlags, true);
3403                        if (top != null) {
3404                            if (top.frontOfTask) {
3405                                // Activity aliases may mean we use different
3406                                // intents for the top activity, so make sure
3407                                // the task now has the identity of the new
3408                                // intent.
3409                                top.task.setIntent(r.intent, r.info);
3410                            }
3411                            logStartActivity(LOG_AM_NEW_INTENT, r, top.task);
3412                            deliverNewIntentLocked(top, r.intent);
3413                        } else {
3414                            // A special case: we need to
3415                            // start the activity because it is not currently
3416                            // running, and the caller has asked to clear the
3417                            // current task to have this activity at the top.
3418                            addingToTask = true;
3419                            // Now pretend like this activity is being started
3420                            // by the top of its task, so it is put in the
3421                            // right place.
3422                            sourceRecord = taskTop;
3423                        }
3424                    } else if (r.realActivity.equals(taskTop.task.realActivity)) {
3425                        // In this case the top activity on the task is the
3426                        // same as the one being launched, so we take that
3427                        // as a request to bring the task to the foreground.
3428                        // If the top activity in the task is the root
3429                        // activity, deliver this new intent to it if it
3430                        // desires.
3431                        if ((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
3432                                && taskTop.realActivity.equals(r.realActivity)) {
3433                            logStartActivity(LOG_AM_NEW_INTENT, r, taskTop.task);
3434                            if (taskTop.frontOfTask) {
3435                                taskTop.task.setIntent(r.intent, r.info);
3436                            }
3437                            deliverNewIntentLocked(taskTop, r.intent);
3438                        } else if (!r.intent.filterEquals(taskTop.task.intent)) {
3439                            // In this case we are launching the root activity
3440                            // of the task, but with a different intent.  We
3441                            // should start a new instance on top.
3442                            addingToTask = true;
3443                            sourceRecord = taskTop;
3444                        }
3445                    } else if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0) {
3446                        // In this case an activity is being launched in to an
3447                        // existing task, without resetting that task.  This
3448                        // is typically the situation of launching an activity
3449                        // from a notification or shortcut.  We want to place
3450                        // the new activity on top of the current task.
3451                        addingToTask = true;
3452                        sourceRecord = taskTop;
3453                    } else if (!taskTop.task.rootWasReset) {
3454                        // In this case we are launching in to an existing task
3455                        // that has not yet been started from its front door.
3456                        // The current task has been brought to the front.
3457                        // Ideally, we'd probably like to place this new task
3458                        // at the bottom of its stack, but that's a little hard
3459                        // to do with the current organization of the code so
3460                        // for now we'll just drop it.
3461                        taskTop.task.setIntent(r.intent, r.info);
3462                    }
3463                    if (!addingToTask) {
3464                        // We didn't do anything...  but it was needed (a.k.a., client
3465                        // don't use that intent!)  And for paranoia, make
3466                        // sure we have correctly resumed the top activity.
3467                        if (doResume) {
3468                            resumeTopActivityLocked(null);
3469                        }
3470                        return START_TASK_TO_FRONT;
3471                    }
3472                }
3473            }
3474        }
3475
3476        //String uri = r.intent.toURI();
3477        //Intent intent2 = new Intent(uri);
3478        //Log.i(TAG, "Given intent: " + r.intent);
3479        //Log.i(TAG, "URI is: " + uri);
3480        //Log.i(TAG, "To intent: " + intent2);
3481
3482        if (r.packageName != null) {
3483            // If the activity being launched is the same as the one currently
3484            // at the top, then we need to check if it should only be launched
3485            // once.
3486            HistoryRecord top = topRunningNonDelayedActivityLocked(notTop);
3487            if (top != null && r.resultTo == null) {
3488                if (top.realActivity.equals(r.realActivity)) {
3489                    if (top.app != null && top.app.thread != null) {
3490                        if ((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
3491                            || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP
3492                            || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
3493                            logStartActivity(LOG_AM_NEW_INTENT, top, top.task);
3494                            // For paranoia, make sure we have correctly
3495                            // resumed the top activity.
3496                            if (doResume) {
3497                                resumeTopActivityLocked(null);
3498                            }
3499                            if (onlyIfNeeded) {
3500                                // We don't need to start a new activity, and
3501                                // the client said not to do anything if that
3502                                // is the case, so this is it!
3503                                return START_RETURN_INTENT_TO_CALLER;
3504                            }
3505                            deliverNewIntentLocked(top, r.intent);
3506                            return START_DELIVERED_TO_TOP;
3507                        }
3508                    }
3509                }
3510            }
3511
3512        } else {
3513            if (r.resultTo != null) {
3514                sendActivityResultLocked(-1,
3515                        r.resultTo, r.resultWho, r.requestCode,
3516                    Activity.RESULT_CANCELED, null);
3517            }
3518            return START_CLASS_NOT_FOUND;
3519        }
3520
3521        boolean newTask = false;
3522
3523        // Should this be considered a new task?
3524        if (r.resultTo == null && !addingToTask
3525                && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
3526            // todo: should do better management of integers.
3527            mCurTask++;
3528            if (mCurTask <= 0) {
3529                mCurTask = 1;
3530            }
3531            r.task = new TaskRecord(mCurTask, r.info, intent,
3532                    (r.info.flags&ActivityInfo.FLAG_CLEAR_TASK_ON_LAUNCH) != 0);
3533            if (DEBUG_TASKS) Log.v(TAG, "Starting new activity " + r
3534                    + " in new task " + r.task);
3535            newTask = true;
3536            addRecentTask(r.task);
3537
3538        } else if (sourceRecord != null) {
3539            if (!addingToTask &&
3540                    (launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
3541                // In this case, we are adding the activity to an existing
3542                // task, but the caller has asked to clear that task if the
3543                // activity is already running.
3544                HistoryRecord top = performClearTaskLocked(
3545                        sourceRecord.task.taskId, r, launchFlags, true);
3546                if (top != null) {
3547                    logStartActivity(LOG_AM_NEW_INTENT, r, top.task);
3548                    deliverNewIntentLocked(top, r.intent);
3549                    // For paranoia, make sure we have correctly
3550                    // resumed the top activity.
3551                    if (doResume) {
3552                        resumeTopActivityLocked(null);
3553                    }
3554                    return START_DELIVERED_TO_TOP;
3555                }
3556            } else if (!addingToTask &&
3557                    (launchFlags&Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) {
3558                // In this case, we are launching an activity in our own task
3559                // that may already be running somewhere in the history, and
3560                // we want to shuffle it to the front of the stack if so.
3561                int where = findActivityInHistoryLocked(r, sourceRecord.task.taskId);
3562                if (where >= 0) {
3563                    HistoryRecord top = moveActivityToFrontLocked(where);
3564                    logStartActivity(LOG_AM_NEW_INTENT, r, top.task);
3565                    deliverNewIntentLocked(top, r.intent);
3566                    if (doResume) {
3567                        resumeTopActivityLocked(null);
3568                    }
3569                    return START_DELIVERED_TO_TOP;
3570                }
3571            }
3572            // An existing activity is starting this new activity, so we want
3573            // to keep the new one in the same task as the one that is starting
3574            // it.
3575            r.task = sourceRecord.task;
3576            if (DEBUG_TASKS) Log.v(TAG, "Starting new activity " + r
3577                    + " in existing task " + r.task);
3578
3579        } else {
3580            // This not being started from an existing activity, and not part
3581            // of a new task...  just put it in the top task, though these days
3582            // this case should never happen.
3583            final int N = mHistory.size();
3584            HistoryRecord prev =
3585                N > 0 ? (HistoryRecord)mHistory.get(N-1) : null;
3586            r.task = prev != null
3587                ? prev.task
3588                : new TaskRecord(mCurTask, r.info, intent,
3589                        (r.info.flags&ActivityInfo.FLAG_CLEAR_TASK_ON_LAUNCH) != 0);
3590            if (DEBUG_TASKS) Log.v(TAG, "Starting new activity " + r
3591                    + " in new guessed " + r.task);
3592        }
3593        if (newTask) {
3594            EventLog.writeEvent(LOG_AM_CREATE_TASK, r.task.taskId);
3595        }
3596        logStartActivity(LOG_AM_CREATE_ACTIVITY, r, r.task);
3597        startActivityLocked(r, newTask, doResume);
3598        return START_SUCCESS;
3599    }
3600
3601    public final int startActivity(IApplicationThread caller,
3602            Intent intent, String resolvedType, Uri[] grantedUriPermissions,
3603            int grantedMode, IBinder resultTo,
3604            String resultWho, int requestCode, boolean onlyIfNeeded,
3605            boolean debug) {
3606        // Refuse possible leaked file descriptors
3607        if (intent != null && intent.hasFileDescriptors()) {
3608            throw new IllegalArgumentException("File descriptors passed in Intent");
3609        }
3610
3611        final boolean componentSpecified = intent.getComponent() != null;
3612
3613        // Don't modify the client's object!
3614        intent = new Intent(intent);
3615
3616        // Collect information about the target of the Intent.
3617        ActivityInfo aInfo;
3618        try {
3619            ResolveInfo rInfo =
3620                ActivityThread.getPackageManager().resolveIntent(
3621                        intent, resolvedType,
3622                        PackageManager.MATCH_DEFAULT_ONLY
3623                        | STOCK_PM_FLAGS);
3624            aInfo = rInfo != null ? rInfo.activityInfo : null;
3625        } catch (RemoteException e) {
3626            aInfo = null;
3627        }
3628
3629        if (aInfo != null) {
3630            // Store the found target back into the intent, because now that
3631            // we have it we never want to do this again.  For example, if the
3632            // user navigates back to this point in the history, we should
3633            // always restart the exact same activity.
3634            intent.setComponent(new ComponentName(
3635                    aInfo.applicationInfo.packageName, aInfo.name));
3636
3637            // Don't debug things in the system process
3638            if (debug) {
3639                if (!aInfo.processName.equals("system")) {
3640                    setDebugApp(aInfo.processName, true, false);
3641                }
3642            }
3643        }
3644
3645        synchronized(this) {
3646            final long origId = Binder.clearCallingIdentity();
3647            int res = startActivityLocked(caller, intent, resolvedType,
3648                    grantedUriPermissions, grantedMode, aInfo,
3649                    resultTo, resultWho, requestCode, -1, -1,
3650                    onlyIfNeeded, componentSpecified);
3651            Binder.restoreCallingIdentity(origId);
3652            return res;
3653        }
3654    }
3655
3656    public int startActivityIntentSender(IApplicationThread caller,
3657            IntentSender intent, Intent fillInIntent, String resolvedType,
3658            IBinder resultTo, String resultWho, int requestCode,
3659            int flagsMask, int flagsValues) {
3660        // Refuse possible leaked file descriptors
3661        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3662            throw new IllegalArgumentException("File descriptors passed in Intent");
3663        }
3664
3665        IIntentSender sender = intent.getTarget();
3666        if (!(sender instanceof PendingIntentRecord)) {
3667            throw new IllegalArgumentException("Bad PendingIntent object");
3668        }
3669
3670        PendingIntentRecord pir = (PendingIntentRecord)sender;
3671
3672        synchronized (this) {
3673            // If this is coming from the currently resumed activity, it is
3674            // effectively saying that app switches are allowed at this point.
3675            if (mResumedActivity != null
3676                    && mResumedActivity.info.applicationInfo.uid ==
3677                            Binder.getCallingUid()) {
3678                mAppSwitchesAllowedTime = 0;
3679            }
3680        }
3681
3682        return pir.sendInner(0, fillInIntent, resolvedType,
3683                null, resultTo, resultWho, requestCode, flagsMask, flagsValues);
3684    }
3685
3686    public boolean startNextMatchingActivity(IBinder callingActivity,
3687            Intent intent) {
3688        // Refuse possible leaked file descriptors
3689        if (intent != null && intent.hasFileDescriptors() == true) {
3690            throw new IllegalArgumentException("File descriptors passed in Intent");
3691        }
3692
3693        synchronized (this) {
3694            int index = indexOfTokenLocked(callingActivity);
3695            if (index < 0) {
3696                return false;
3697            }
3698            HistoryRecord r = (HistoryRecord)mHistory.get(index);
3699            if (r.app == null || r.app.thread == null) {
3700                // The caller is not running...  d'oh!
3701                return false;
3702            }
3703            intent = new Intent(intent);
3704            // The caller is not allowed to change the data.
3705            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3706            // And we are resetting to find the next component...
3707            intent.setComponent(null);
3708
3709            ActivityInfo aInfo = null;
3710            try {
3711                List<ResolveInfo> resolves =
3712                    ActivityThread.getPackageManager().queryIntentActivities(
3713                            intent, r.resolvedType,
3714                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS);
3715
3716                // Look for the original activity in the list...
3717                final int N = resolves != null ? resolves.size() : 0;
3718                for (int i=0; i<N; i++) {
3719                    ResolveInfo rInfo = resolves.get(i);
3720                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3721                            && rInfo.activityInfo.name.equals(r.info.name)) {
3722                        // We found the current one...  the next matching is
3723                        // after it.
3724                        i++;
3725                        if (i<N) {
3726                            aInfo = resolves.get(i).activityInfo;
3727                        }
3728                        break;
3729                    }
3730                }
3731            } catch (RemoteException e) {
3732            }
3733
3734            if (aInfo == null) {
3735                // Nobody who is next!
3736                return false;
3737            }
3738
3739            intent.setComponent(new ComponentName(
3740                    aInfo.applicationInfo.packageName, aInfo.name));
3741            intent.setFlags(intent.getFlags()&~(
3742                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3743                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3744                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3745                    Intent.FLAG_ACTIVITY_NEW_TASK));
3746
3747            // Okay now we need to start the new activity, replacing the
3748            // currently running activity.  This is a little tricky because
3749            // we want to start the new one as if the current one is finished,
3750            // but not finish the current one first so that there is no flicker.
3751            // And thus...
3752            final boolean wasFinishing = r.finishing;
3753            r.finishing = true;
3754
3755            // Propagate reply information over to the new activity.
3756            final HistoryRecord resultTo = r.resultTo;
3757            final String resultWho = r.resultWho;
3758            final int requestCode = r.requestCode;
3759            r.resultTo = null;
3760            if (resultTo != null) {
3761                resultTo.removeResultsLocked(r, resultWho, requestCode);
3762            }
3763
3764            final long origId = Binder.clearCallingIdentity();
3765            // XXX we are not dealing with propagating grantedUriPermissions...
3766            // those are not yet exposed to user code, so there is no need.
3767            int res = startActivityLocked(r.app.thread, intent,
3768                    r.resolvedType, null, 0, aInfo, resultTo, resultWho,
3769                    requestCode, -1, r.launchedFromUid, false, false);
3770            Binder.restoreCallingIdentity(origId);
3771
3772            r.finishing = wasFinishing;
3773            if (res != START_SUCCESS) {
3774                return false;
3775            }
3776            return true;
3777        }
3778    }
3779
3780    public final int startActivityInPackage(int uid,
3781            Intent intent, String resolvedType, IBinder resultTo,
3782            String resultWho, int requestCode, boolean onlyIfNeeded) {
3783
3784        // This is so super not safe, that only the system (or okay root)
3785        // can do it.
3786        final int callingUid = Binder.getCallingUid();
3787        if (callingUid != 0 && callingUid != Process.myUid()) {
3788            throw new SecurityException(
3789                    "startActivityInPackage only available to the system");
3790        }
3791
3792        final boolean componentSpecified = intent.getComponent() != null;
3793
3794        // Don't modify the client's object!
3795        intent = new Intent(intent);
3796
3797        // Collect information about the target of the Intent.
3798        ActivityInfo aInfo;
3799        try {
3800            ResolveInfo rInfo =
3801                ActivityThread.getPackageManager().resolveIntent(
3802                        intent, resolvedType,
3803                        PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS);
3804            aInfo = rInfo != null ? rInfo.activityInfo : null;
3805        } catch (RemoteException e) {
3806            aInfo = null;
3807        }
3808
3809        if (aInfo != null) {
3810            // Store the found target back into the intent, because now that
3811            // we have it we never want to do this again.  For example, if the
3812            // user navigates back to this point in the history, we should
3813            // always restart the exact same activity.
3814            intent.setComponent(new ComponentName(
3815                    aInfo.applicationInfo.packageName, aInfo.name));
3816        }
3817
3818        synchronized(this) {
3819            return startActivityLocked(null, intent, resolvedType,
3820                    null, 0, aInfo, resultTo, resultWho, requestCode, -1, uid,
3821                    onlyIfNeeded, componentSpecified);
3822        }
3823    }
3824
3825    private final void addRecentTask(TaskRecord task) {
3826        // Remove any existing entries that are the same kind of task.
3827        int N = mRecentTasks.size();
3828        for (int i=0; i<N; i++) {
3829            TaskRecord tr = mRecentTasks.get(i);
3830            if ((task.affinity != null && task.affinity.equals(tr.affinity))
3831                    || (task.intent != null && task.intent.filterEquals(tr.intent))) {
3832                mRecentTasks.remove(i);
3833                i--;
3834                N--;
3835                if (task.intent == null) {
3836                    // If the new recent task we are adding is not fully
3837                    // specified, then replace it with the existing recent task.
3838                    task = tr;
3839                }
3840            }
3841        }
3842        if (N >= MAX_RECENT_TASKS) {
3843            mRecentTasks.remove(N-1);
3844        }
3845        mRecentTasks.add(0, task);
3846    }
3847
3848    public void setRequestedOrientation(IBinder token,
3849            int requestedOrientation) {
3850        synchronized (this) {
3851            int index = indexOfTokenLocked(token);
3852            if (index < 0) {
3853                return;
3854            }
3855            HistoryRecord r = (HistoryRecord)mHistory.get(index);
3856            final long origId = Binder.clearCallingIdentity();
3857            mWindowManager.setAppOrientation(r, requestedOrientation);
3858            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3859                    mConfiguration,
3860                    r.mayFreezeScreenLocked(r.app) ? r : null);
3861            if (config != null) {
3862                r.frozenBeforeDestroy = true;
3863                if (!updateConfigurationLocked(config, r)) {
3864                    resumeTopActivityLocked(null);
3865                }
3866            }
3867            Binder.restoreCallingIdentity(origId);
3868        }
3869    }
3870
3871    public int getRequestedOrientation(IBinder token) {
3872        synchronized (this) {
3873            int index = indexOfTokenLocked(token);
3874            if (index < 0) {
3875                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3876            }
3877            HistoryRecord r = (HistoryRecord)mHistory.get(index);
3878            return mWindowManager.getAppOrientation(r);
3879        }
3880    }
3881
3882    private final void stopActivityLocked(HistoryRecord r) {
3883        if (DEBUG_SWITCH) Log.d(TAG, "Stopping: " + r);
3884        if ((r.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_HISTORY) != 0
3885                || (r.info.flags&ActivityInfo.FLAG_NO_HISTORY) != 0) {
3886            if (!r.finishing) {
3887                requestFinishActivityLocked(r, Activity.RESULT_CANCELED, null,
3888                        "no-history");
3889            }
3890        } else if (r.app != null && r.app.thread != null) {
3891            if (mFocusedActivity == r) {
3892                setFocusedActivityLocked(topRunningActivityLocked(null));
3893            }
3894            r.resumeKeyDispatchingLocked();
3895            try {
3896                r.stopped = false;
3897                r.state = ActivityState.STOPPING;
3898                if (DEBUG_VISBILITY) Log.v(
3899                        TAG, "Stopping visible=" + r.visible + " for " + r);
3900                if (!r.visible) {
3901                    mWindowManager.setAppVisibility(r, false);
3902                }
3903                r.app.thread.scheduleStopActivity(r, r.visible, r.configChangeFlags);
3904            } catch (Exception e) {
3905                // Maybe just ignore exceptions here...  if the process
3906                // has crashed, our death notification will clean things
3907                // up.
3908                Log.w(TAG, "Exception thrown during pause", e);
3909                // Just in case, assume it to be stopped.
3910                r.stopped = true;
3911                r.state = ActivityState.STOPPED;
3912                if (r.configDestroy) {
3913                    destroyActivityLocked(r, true);
3914                }
3915            }
3916        }
3917    }
3918
3919    /**
3920     * @return Returns true if the activity is being finished, false if for
3921     * some reason it is being left as-is.
3922     */
3923    private final boolean requestFinishActivityLocked(IBinder token, int resultCode,
3924            Intent resultData, String reason) {
3925        if (DEBUG_RESULTS) Log.v(
3926            TAG, "Finishing activity: token=" + token
3927            + ", result=" + resultCode + ", data=" + resultData);
3928
3929        int index = indexOfTokenLocked(token);
3930        if (index < 0) {
3931            return false;
3932        }
3933        HistoryRecord r = (HistoryRecord)mHistory.get(index);
3934
3935        // Is this the last activity left?
3936        boolean lastActivity = true;
3937        for (int i=mHistory.size()-1; i>=0; i--) {
3938            HistoryRecord p = (HistoryRecord)mHistory.get(i);
3939            if (!p.finishing && p != r) {
3940                lastActivity = false;
3941                break;
3942            }
3943        }
3944
3945        // If this is the last activity, but it is the home activity, then
3946        // just don't finish it.
3947        if (lastActivity) {
3948            if (r.intent.hasCategory(Intent.CATEGORY_HOME)) {
3949                return false;
3950            }
3951        }
3952
3953        finishActivityLocked(r, index, resultCode, resultData, reason);
3954        return true;
3955    }
3956
3957    /**
3958     * @return Returns true if this activity has been removed from the history
3959     * list, or false if it is still in the list and will be removed later.
3960     */
3961    private final boolean finishActivityLocked(HistoryRecord r, int index,
3962            int resultCode, Intent resultData, String reason) {
3963        if (r.finishing) {
3964            Log.w(TAG, "Duplicate finish request for " + r);
3965            return false;
3966        }
3967
3968        r.finishing = true;
3969        EventLog.writeEvent(LOG_AM_FINISH_ACTIVITY,
3970                System.identityHashCode(r),
3971                r.task.taskId, r.shortComponentName, reason);
3972        r.task.numActivities--;
3973        if (r.frontOfTask && index < (mHistory.size()-1)) {
3974            HistoryRecord next = (HistoryRecord)mHistory.get(index+1);
3975            if (next.task == r.task) {
3976                next.frontOfTask = true;
3977            }
3978        }
3979
3980        r.pauseKeyDispatchingLocked();
3981        if (mFocusedActivity == r) {
3982            setFocusedActivityLocked(topRunningActivityLocked(null));
3983        }
3984
3985        // send the result
3986        HistoryRecord resultTo = r.resultTo;
3987        if (resultTo != null) {
3988            if (DEBUG_RESULTS) Log.v(TAG, "Adding result to " + resultTo
3989                    + " who=" + r.resultWho + " req=" + r.requestCode
3990                    + " res=" + resultCode + " data=" + resultData);
3991            if (r.info.applicationInfo.uid > 0) {
3992                grantUriPermissionFromIntentLocked(r.info.applicationInfo.uid,
3993                        r.packageName, resultData, r);
3994            }
3995            resultTo.addResultLocked(r, r.resultWho, r.requestCode, resultCode,
3996                                     resultData);
3997            r.resultTo = null;
3998        }
3999        else if (DEBUG_RESULTS) Log.v(TAG, "No result destination from " + r);
4000
4001        // Make sure this HistoryRecord is not holding on to other resources,
4002        // because clients have remote IPC references to this object so we
4003        // can't assume that will go away and want to avoid circular IPC refs.
4004        r.results = null;
4005        r.pendingResults = null;
4006        r.newIntents = null;
4007        r.icicle = null;
4008
4009        if (mPendingThumbnails.size() > 0) {
4010            // There are clients waiting to receive thumbnails so, in case
4011            // this is an activity that someone is waiting for, add it
4012            // to the pending list so we can correctly update the clients.
4013            mCancelledThumbnails.add(r);
4014        }
4015
4016        if (mResumedActivity == r) {
4017            boolean endTask = index <= 0
4018                    || ((HistoryRecord)mHistory.get(index-1)).task != r.task;
4019            if (DEBUG_TRANSITION) Log.v(TAG,
4020                    "Prepare close transition: finishing " + r);
4021            mWindowManager.prepareAppTransition(endTask
4022                    ? WindowManagerPolicy.TRANSIT_TASK_CLOSE
4023                    : WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE);
4024
4025            // Tell window manager to prepare for this one to be removed.
4026            mWindowManager.setAppVisibility(r, false);
4027
4028            if (mPausingActivity == null) {
4029                if (DEBUG_PAUSE) Log.v(TAG, "Finish needs to pause: " + r);
4030                if (DEBUG_USER_LEAVING) Log.v(TAG, "finish() => pause with userLeaving=false");
4031                startPausingLocked(false, false);
4032            }
4033
4034        } else if (r.state != ActivityState.PAUSING) {
4035            // If the activity is PAUSING, we will complete the finish once
4036            // it is done pausing; else we can just directly finish it here.
4037            if (DEBUG_PAUSE) Log.v(TAG, "Finish not pausing: " + r);
4038            return finishCurrentActivityLocked(r, index,
4039                    FINISH_AFTER_PAUSE) == null;
4040        } else {
4041            if (DEBUG_PAUSE) Log.v(TAG, "Finish waiting for pause of: " + r);
4042        }
4043
4044        return false;
4045    }
4046
4047    private static final int FINISH_IMMEDIATELY = 0;
4048    private static final int FINISH_AFTER_PAUSE = 1;
4049    private static final int FINISH_AFTER_VISIBLE = 2;
4050
4051    private final HistoryRecord finishCurrentActivityLocked(HistoryRecord r,
4052            int mode) {
4053        final int index = indexOfTokenLocked(r);
4054        if (index < 0) {
4055            return null;
4056        }
4057
4058        return finishCurrentActivityLocked(r, index, mode);
4059    }
4060
4061    private final HistoryRecord finishCurrentActivityLocked(HistoryRecord r,
4062            int index, int mode) {
4063        // First things first: if this activity is currently visible,
4064        // and the resumed activity is not yet visible, then hold off on
4065        // finishing until the resumed one becomes visible.
4066        if (mode == FINISH_AFTER_VISIBLE && r.nowVisible) {
4067            if (!mStoppingActivities.contains(r)) {
4068                mStoppingActivities.add(r);
4069                if (mStoppingActivities.size() > 3) {
4070                    // If we already have a few activities waiting to stop,
4071                    // then give up on things going idle and start clearing
4072                    // them out.
4073                    Message msg = Message.obtain();
4074                    msg.what = ActivityManagerService.IDLE_NOW_MSG;
4075                    mHandler.sendMessage(msg);
4076                }
4077            }
4078            r.state = ActivityState.STOPPING;
4079            updateOomAdjLocked();
4080            return r;
4081        }
4082
4083        // make sure the record is cleaned out of other places.
4084        mStoppingActivities.remove(r);
4085        mWaitingVisibleActivities.remove(r);
4086        if (mResumedActivity == r) {
4087            mResumedActivity = null;
4088        }
4089        final ActivityState prevState = r.state;
4090        r.state = ActivityState.FINISHING;
4091
4092        if (mode == FINISH_IMMEDIATELY
4093                || prevState == ActivityState.STOPPED
4094                || prevState == ActivityState.INITIALIZING) {
4095            // If this activity is already stopped, we can just finish
4096            // it right now.
4097            return destroyActivityLocked(r, true) ? null : r;
4098        } else {
4099            // Need to go through the full pause cycle to get this
4100            // activity into the stopped state and then finish it.
4101            if (localLOGV) Log.v(TAG, "Enqueueing pending finish: " + r);
4102            mFinishingActivities.add(r);
4103            resumeTopActivityLocked(null);
4104        }
4105        return r;
4106    }
4107
4108    /**
4109     * This is the internal entry point for handling Activity.finish().
4110     *
4111     * @param token The Binder token referencing the Activity we want to finish.
4112     * @param resultCode Result code, if any, from this Activity.
4113     * @param resultData Result data (Intent), if any, from this Activity.
4114     *
4115     * @result Returns true if the activity successfully finished, or false if it is still running.
4116     */
4117    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
4118        // Refuse possible leaked file descriptors
4119        if (resultData != null && resultData.hasFileDescriptors() == true) {
4120            throw new IllegalArgumentException("File descriptors passed in Intent");
4121        }
4122
4123        synchronized(this) {
4124            if (mController != null) {
4125                // Find the first activity that is not finishing.
4126                HistoryRecord next = topRunningActivityLocked(token, 0);
4127                if (next != null) {
4128                    // ask watcher if this is allowed
4129                    boolean resumeOK = true;
4130                    try {
4131                        resumeOK = mController.activityResuming(next.packageName);
4132                    } catch (RemoteException e) {
4133                        mController = null;
4134                    }
4135
4136                    if (!resumeOK) {
4137                        return false;
4138                    }
4139                }
4140            }
4141            final long origId = Binder.clearCallingIdentity();
4142            boolean res = requestFinishActivityLocked(token, resultCode,
4143                    resultData, "app-request");
4144            Binder.restoreCallingIdentity(origId);
4145            return res;
4146        }
4147    }
4148
4149    void sendActivityResultLocked(int callingUid, HistoryRecord r,
4150            String resultWho, int requestCode, int resultCode, Intent data) {
4151
4152        if (callingUid > 0) {
4153            grantUriPermissionFromIntentLocked(callingUid, r.packageName,
4154                    data, r);
4155        }
4156
4157        if (DEBUG_RESULTS) Log.v(TAG, "Send activity result to " + r
4158                + " : who=" + resultWho + " req=" + requestCode
4159                + " res=" + resultCode + " data=" + data);
4160        if (mResumedActivity == r && r.app != null && r.app.thread != null) {
4161            try {
4162                ArrayList<ResultInfo> list = new ArrayList<ResultInfo>();
4163                list.add(new ResultInfo(resultWho, requestCode,
4164                        resultCode, data));
4165                r.app.thread.scheduleSendResult(r, list);
4166                return;
4167            } catch (Exception e) {
4168                Log.w(TAG, "Exception thrown sending result to " + r, e);
4169            }
4170        }
4171
4172        r.addResultLocked(null, resultWho, requestCode, resultCode, data);
4173    }
4174
4175    public final void finishSubActivity(IBinder token, String resultWho,
4176            int requestCode) {
4177        synchronized(this) {
4178            int index = indexOfTokenLocked(token);
4179            if (index < 0) {
4180                return;
4181            }
4182            HistoryRecord self = (HistoryRecord)mHistory.get(index);
4183
4184            final long origId = Binder.clearCallingIdentity();
4185
4186            int i;
4187            for (i=mHistory.size()-1; i>=0; i--) {
4188                HistoryRecord r = (HistoryRecord)mHistory.get(i);
4189                if (r.resultTo == self && r.requestCode == requestCode) {
4190                    if ((r.resultWho == null && resultWho == null) ||
4191                        (r.resultWho != null && r.resultWho.equals(resultWho))) {
4192                        finishActivityLocked(r, i,
4193                                Activity.RESULT_CANCELED, null, "request-sub");
4194                    }
4195                }
4196            }
4197
4198            Binder.restoreCallingIdentity(origId);
4199        }
4200    }
4201
4202    public void overridePendingTransition(IBinder token, String packageName,
4203            int enterAnim, int exitAnim) {
4204        synchronized(this) {
4205            int index = indexOfTokenLocked(token);
4206            if (index < 0) {
4207                return;
4208            }
4209            HistoryRecord self = (HistoryRecord)mHistory.get(index);
4210
4211            final long origId = Binder.clearCallingIdentity();
4212
4213            if (self.state == ActivityState.RESUMED
4214                    || self.state == ActivityState.PAUSING) {
4215                mWindowManager.overridePendingAppTransition(packageName,
4216                        enterAnim, exitAnim);
4217            }
4218
4219            Binder.restoreCallingIdentity(origId);
4220        }
4221    }
4222
4223    /**
4224     * Perform clean-up of service connections in an activity record.
4225     */
4226    private final void cleanUpActivityServicesLocked(HistoryRecord r) {
4227        // Throw away any services that have been bound by this activity.
4228        if (r.connections != null) {
4229            Iterator<ConnectionRecord> it = r.connections.iterator();
4230            while (it.hasNext()) {
4231                ConnectionRecord c = it.next();
4232                removeConnectionLocked(c, null, r);
4233            }
4234            r.connections = null;
4235        }
4236    }
4237
4238    /**
4239     * Perform the common clean-up of an activity record.  This is called both
4240     * as part of destroyActivityLocked() (when destroying the client-side
4241     * representation) and cleaning things up as a result of its hosting
4242     * processing going away, in which case there is no remaining client-side
4243     * state to destroy so only the cleanup here is needed.
4244     */
4245    private final void cleanUpActivityLocked(HistoryRecord r, boolean cleanServices) {
4246        if (mResumedActivity == r) {
4247            mResumedActivity = null;
4248        }
4249        if (mFocusedActivity == r) {
4250            mFocusedActivity = null;
4251        }
4252
4253        r.configDestroy = false;
4254        r.frozenBeforeDestroy = false;
4255
4256        // Make sure this record is no longer in the pending finishes list.
4257        // This could happen, for example, if we are trimming activities
4258        // down to the max limit while they are still waiting to finish.
4259        mFinishingActivities.remove(r);
4260        mWaitingVisibleActivities.remove(r);
4261
4262        // Remove any pending results.
4263        if (r.finishing && r.pendingResults != null) {
4264            for (WeakReference<PendingIntentRecord> apr : r.pendingResults) {
4265                PendingIntentRecord rec = apr.get();
4266                if (rec != null) {
4267                    cancelIntentSenderLocked(rec, false);
4268                }
4269            }
4270            r.pendingResults = null;
4271        }
4272
4273        if (cleanServices) {
4274            cleanUpActivityServicesLocked(r);
4275        }
4276
4277        if (mPendingThumbnails.size() > 0) {
4278            // There are clients waiting to receive thumbnails so, in case
4279            // this is an activity that someone is waiting for, add it
4280            // to the pending list so we can correctly update the clients.
4281            mCancelledThumbnails.add(r);
4282        }
4283
4284        // Get rid of any pending idle timeouts.
4285        mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);
4286        mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
4287    }
4288
4289    private final void removeActivityFromHistoryLocked(HistoryRecord r) {
4290        if (r.state != ActivityState.DESTROYED) {
4291            mHistory.remove(r);
4292            r.inHistory = false;
4293            r.state = ActivityState.DESTROYED;
4294            mWindowManager.removeAppToken(r);
4295            if (VALIDATE_TOKENS) {
4296                mWindowManager.validateAppTokens(mHistory);
4297            }
4298            cleanUpActivityServicesLocked(r);
4299            removeActivityUriPermissionsLocked(r);
4300        }
4301    }
4302
4303    /**
4304     * Destroy the current CLIENT SIDE instance of an activity.  This may be
4305     * called both when actually finishing an activity, or when performing
4306     * a configuration switch where we destroy the current client-side object
4307     * but then create a new client-side object for this same HistoryRecord.
4308     */
4309    private final boolean destroyActivityLocked(HistoryRecord r,
4310            boolean removeFromApp) {
4311        if (DEBUG_SWITCH) Log.v(
4312            TAG, "Removing activity: token=" + r
4313              + ", app=" + (r.app != null ? r.app.processName : "(null)"));
4314        EventLog.writeEvent(LOG_AM_DESTROY_ACTIVITY,
4315                System.identityHashCode(r),
4316                r.task.taskId, r.shortComponentName);
4317
4318        boolean removedFromHistory = false;
4319
4320        cleanUpActivityLocked(r, false);
4321
4322        if (r.app != null) {
4323            if (removeFromApp) {
4324                int idx = r.app.activities.indexOf(r);
4325                if (idx >= 0) {
4326                    r.app.activities.remove(idx);
4327                }
4328                if (r.persistent) {
4329                    decPersistentCountLocked(r.app);
4330                }
4331            }
4332
4333            boolean skipDestroy = false;
4334
4335            try {
4336                if (DEBUG_SWITCH) Log.i(TAG, "Destroying: " + r);
4337                r.app.thread.scheduleDestroyActivity(r, r.finishing,
4338                        r.configChangeFlags);
4339            } catch (Exception e) {
4340                // We can just ignore exceptions here...  if the process
4341                // has crashed, our death notification will clean things
4342                // up.
4343                //Log.w(TAG, "Exception thrown during finish", e);
4344                if (r.finishing) {
4345                    removeActivityFromHistoryLocked(r);
4346                    removedFromHistory = true;
4347                    skipDestroy = true;
4348                }
4349            }
4350
4351            r.app = null;
4352            r.nowVisible = false;
4353
4354            if (r.finishing && !skipDestroy) {
4355                r.state = ActivityState.DESTROYING;
4356                Message msg = mHandler.obtainMessage(DESTROY_TIMEOUT_MSG);
4357                msg.obj = r;
4358                mHandler.sendMessageDelayed(msg, DESTROY_TIMEOUT);
4359            } else {
4360                r.state = ActivityState.DESTROYED;
4361            }
4362        } else {
4363            // remove this record from the history.
4364            if (r.finishing) {
4365                removeActivityFromHistoryLocked(r);
4366                removedFromHistory = true;
4367            } else {
4368                r.state = ActivityState.DESTROYED;
4369            }
4370        }
4371
4372        r.configChangeFlags = 0;
4373
4374        if (!mLRUActivities.remove(r)) {
4375            Log.w(TAG, "Activity " + r + " being finished, but not in LRU list");
4376        }
4377
4378        return removedFromHistory;
4379    }
4380
4381    private static void removeHistoryRecordsForAppLocked(ArrayList list,
4382                                                         ProcessRecord app)
4383    {
4384        int i = list.size();
4385        if (localLOGV) Log.v(
4386            TAG, "Removing app " + app + " from list " + list
4387            + " with " + i + " entries");
4388        while (i > 0) {
4389            i--;
4390            HistoryRecord r = (HistoryRecord)list.get(i);
4391            if (localLOGV) Log.v(
4392                TAG, "Record #" + i + " " + r + ": app=" + r.app);
4393            if (r.app == app) {
4394                if (localLOGV) Log.v(TAG, "Removing this entry!");
4395                list.remove(i);
4396            }
4397        }
4398    }
4399
4400    /**
4401     * Main function for removing an existing process from the activity manager
4402     * as a result of that process going away.  Clears out all connections
4403     * to the process.
4404     */
4405    private final void handleAppDiedLocked(ProcessRecord app,
4406            boolean restarting) {
4407        cleanUpApplicationRecordLocked(app, restarting, -1);
4408        if (!restarting) {
4409            mLRUProcesses.remove(app);
4410        }
4411
4412        // Just in case...
4413        if (mPausingActivity != null && mPausingActivity.app == app) {
4414            if (DEBUG_PAUSE) Log.v(TAG, "App died while pausing: " + mPausingActivity);
4415            mPausingActivity = null;
4416        }
4417        if (mLastPausedActivity != null && mLastPausedActivity.app == app) {
4418            mLastPausedActivity = null;
4419        }
4420
4421        // Remove this application's activities from active lists.
4422        removeHistoryRecordsForAppLocked(mLRUActivities, app);
4423        removeHistoryRecordsForAppLocked(mStoppingActivities, app);
4424        removeHistoryRecordsForAppLocked(mWaitingVisibleActivities, app);
4425        removeHistoryRecordsForAppLocked(mFinishingActivities, app);
4426
4427        boolean atTop = true;
4428        boolean hasVisibleActivities = false;
4429
4430        // Clean out the history list.
4431        int i = mHistory.size();
4432        if (localLOGV) Log.v(
4433            TAG, "Removing app " + app + " from history with " + i + " entries");
4434        while (i > 0) {
4435            i--;
4436            HistoryRecord r = (HistoryRecord)mHistory.get(i);
4437            if (localLOGV) Log.v(
4438                TAG, "Record #" + i + " " + r + ": app=" + r.app);
4439            if (r.app == app) {
4440                if ((!r.haveState && !r.stateNotNeeded) || r.finishing) {
4441                    if (localLOGV) Log.v(
4442                        TAG, "Removing this entry!  frozen=" + r.haveState
4443                        + " finishing=" + r.finishing);
4444                    mHistory.remove(i);
4445
4446                    r.inHistory = false;
4447                    mWindowManager.removeAppToken(r);
4448                    if (VALIDATE_TOKENS) {
4449                        mWindowManager.validateAppTokens(mHistory);
4450                    }
4451                    removeActivityUriPermissionsLocked(r);
4452
4453                } else {
4454                    // We have the current state for this activity, so
4455                    // it can be restarted later when needed.
4456                    if (localLOGV) Log.v(
4457                        TAG, "Keeping entry, setting app to null");
4458                    if (r.visible) {
4459                        hasVisibleActivities = true;
4460                    }
4461                    r.app = null;
4462                    r.nowVisible = false;
4463                    if (!r.haveState) {
4464                        r.icicle = null;
4465                    }
4466                }
4467
4468                cleanUpActivityLocked(r, true);
4469                r.state = ActivityState.STOPPED;
4470            }
4471            atTop = false;
4472        }
4473
4474        app.activities.clear();
4475
4476        if (app.instrumentationClass != null) {
4477            Log.w(TAG, "Crash of app " + app.processName
4478                  + " running instrumentation " + app.instrumentationClass);
4479            Bundle info = new Bundle();
4480            info.putString("shortMsg", "Process crashed.");
4481            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4482        }
4483
4484        if (!restarting) {
4485            if (!resumeTopActivityLocked(null)) {
4486                // If there was nothing to resume, and we are not already
4487                // restarting this process, but there is a visible activity that
4488                // is hosted by the process...  then make sure all visible
4489                // activities are running, taking care of restarting this
4490                // process.
4491                if (hasVisibleActivities) {
4492                    ensureActivitiesVisibleLocked(null, 0);
4493                }
4494            }
4495        }
4496    }
4497
4498    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4499        IBinder threadBinder = thread.asBinder();
4500
4501        // Find the application record.
4502        int count = mLRUProcesses.size();
4503        int i;
4504        for (i=0; i<count; i++) {
4505            ProcessRecord rec = mLRUProcesses.get(i);
4506            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4507                return i;
4508            }
4509        }
4510        return -1;
4511    }
4512
4513    private final ProcessRecord getRecordForAppLocked(
4514            IApplicationThread thread) {
4515        if (thread == null) {
4516            return null;
4517        }
4518
4519        int appIndex = getLRURecordIndexForAppLocked(thread);
4520        return appIndex >= 0 ? mLRUProcesses.get(appIndex) : null;
4521    }
4522
4523    private final void appDiedLocked(ProcessRecord app, int pid,
4524            IApplicationThread thread) {
4525
4526        mProcDeaths[0]++;
4527
4528        if (app.thread != null && app.thread.asBinder() == thread.asBinder()) {
4529            Log.i(TAG, "Process " + app.processName + " (pid " + pid
4530                    + ") has died.");
4531            EventLog.writeEvent(LOG_AM_PROCESS_DIED, app.pid, app.processName);
4532            if (localLOGV) Log.v(
4533                TAG, "Dying app: " + app + ", pid: " + pid
4534                + ", thread: " + thread.asBinder());
4535            boolean doLowMem = app.instrumentationClass == null;
4536            handleAppDiedLocked(app, false);
4537
4538            if (doLowMem) {
4539                // If there are no longer any background processes running,
4540                // and the app that died was not running instrumentation,
4541                // then tell everyone we are now low on memory.
4542                boolean haveBg = false;
4543                int count = mLRUProcesses.size();
4544                int i;
4545                for (i=0; i<count; i++) {
4546                    ProcessRecord rec = mLRUProcesses.get(i);
4547                    if (rec.thread != null && rec.setAdj >= HIDDEN_APP_MIN_ADJ) {
4548                        haveBg = true;
4549                        break;
4550                    }
4551                }
4552
4553                if (!haveBg) {
4554                    Log.i(TAG, "Low Memory: No more background processes.");
4555                    EventLog.writeEvent(LOG_AM_LOW_MEMORY, mLRUProcesses.size());
4556                    long now = SystemClock.uptimeMillis();
4557                    for (i=0; i<count; i++) {
4558                        ProcessRecord rec = mLRUProcesses.get(i);
4559                        if (rec.thread != null &&
4560                                (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4561                            // The low memory report is overriding any current
4562                            // state for a GC request.  Make sure to do
4563                            // visible/foreground processes first.
4564                            if (rec.setAdj <= VISIBLE_APP_ADJ) {
4565                                rec.lastRequestedGc = 0;
4566                            } else {
4567                                rec.lastRequestedGc = rec.lastLowMemory;
4568                            }
4569                            rec.reportLowMemory = true;
4570                            rec.lastLowMemory = now;
4571                            mProcessesToGc.remove(rec);
4572                            addProcessToGcListLocked(rec);
4573                        }
4574                    }
4575                    scheduleAppGcsLocked();
4576                }
4577            }
4578        } else if (Config.LOGD) {
4579            Log.d(TAG, "Received spurious death notification for thread "
4580                    + thread.asBinder());
4581        }
4582    }
4583
4584    final String readFile(String filename) {
4585        try {
4586            FileInputStream fs = new FileInputStream(filename);
4587            byte[] inp = new byte[8192];
4588            int size = fs.read(inp);
4589            fs.close();
4590            return new String(inp, 0, 0, size);
4591        } catch (java.io.IOException e) {
4592        }
4593        return "";
4594    }
4595
4596    final void appNotRespondingLocked(ProcessRecord app, HistoryRecord activity,
4597            HistoryRecord reportedActivity, final String annotation) {
4598        if (app.notResponding || app.crashing) {
4599            return;
4600        }
4601
4602        // Log the ANR to the event log.
4603        EventLog.writeEvent(LOG_ANR, app.pid, app.processName, annotation);
4604
4605        // If we are on a secure build and the application is not interesting to the user (it is
4606        // not visible or in the background), just kill it instead of displaying a dialog.
4607        boolean isSecure = "1".equals(SystemProperties.get(SYSTEM_SECURE, "0"));
4608        if (isSecure && !app.isInterestingToUserLocked() && Process.myPid() != app.pid) {
4609            Process.killProcess(app.pid);
4610            return;
4611        }
4612
4613        // DeviceMonitor.start();
4614
4615        String processInfo = null;
4616        if (MONITOR_CPU_USAGE) {
4617            updateCpuStatsNow();
4618            synchronized (mProcessStatsThread) {
4619                processInfo = mProcessStats.printCurrentState();
4620            }
4621        }
4622
4623        StringBuilder info = mStringBuilder;
4624        info.setLength(0);
4625        info.append("ANR in process: ");
4626        info.append(app.processName);
4627        if (reportedActivity != null && reportedActivity.app != null) {
4628            info.append(" (last in ");
4629            info.append(reportedActivity.app.processName);
4630            info.append(")");
4631        }
4632        if (annotation != null) {
4633            info.append("\nAnnotation: ");
4634            info.append(annotation);
4635        }
4636        if (MONITOR_CPU_USAGE) {
4637            info.append("\nCPU usage:\n");
4638            info.append(processInfo);
4639        }
4640        Log.i(TAG, info.toString());
4641
4642        // The application is not responding. Dump as many thread traces as we can.
4643        boolean fileDump = prepareTraceFile(true);
4644        if (!fileDump) {
4645            // Dumping traces to the log, just dump the process that isn't responding so
4646            // we don't overflow the log
4647            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4648        } else {
4649            // Dumping traces to a file so dump all active processes we know about
4650            synchronized (this) {
4651                // First, these are the most important processes.
4652                final int[] imppids = new int[3];
4653                int i=0;
4654                imppids[0] = app.pid;
4655                i++;
4656                if (reportedActivity != null && reportedActivity.app != null
4657                        && reportedActivity.app.thread != null
4658                        && reportedActivity.app.pid != app.pid) {
4659                    imppids[i] = reportedActivity.app.pid;
4660                    i++;
4661                }
4662                imppids[i] = Process.myPid();
4663                for (i=0; i<imppids.length && imppids[i] != 0; i++) {
4664                    Process.sendSignal(imppids[i], Process.SIGNAL_QUIT);
4665                    synchronized (this) {
4666                        try {
4667                            wait(200);
4668                        } catch (InterruptedException e) {
4669                        }
4670                    }
4671                }
4672                for (i = mLRUProcesses.size() - 1 ; i >= 0 ; i--) {
4673                    ProcessRecord r = mLRUProcesses.get(i);
4674                    boolean done = false;
4675                    for (int j=0; j<imppids.length && imppids[j] != 0; j++) {
4676                        if (imppids[j] == r.pid) {
4677                            done = true;
4678                            break;
4679                        }
4680                    }
4681                    if (!done && r.thread != null) {
4682                        Process.sendSignal(r.pid, Process.SIGNAL_QUIT);
4683                        synchronized (this) {
4684                            try {
4685                                wait(200);
4686                            } catch (InterruptedException e) {
4687                            }
4688                        }
4689                    }
4690                }
4691            }
4692        }
4693
4694        if (mController != null) {
4695            try {
4696                int res = mController.appNotResponding(app.processName,
4697                        app.pid, info.toString());
4698                if (res != 0) {
4699                    if (res < 0) {
4700                        // wait until the SIGQUIT has had a chance to process before killing the
4701                        // process.
4702                        try {
4703                            wait(2000);
4704                        } catch (InterruptedException e) {
4705                        }
4706
4707                        Process.killProcess(app.pid);
4708                        return;
4709                    }
4710                }
4711            } catch (RemoteException e) {
4712                mController = null;
4713            }
4714        }
4715
4716        makeAppNotRespondingLocked(app,
4717                activity != null ? activity.shortComponentName : null,
4718                annotation != null ? "ANR " + annotation : "ANR",
4719                info.toString(), null);
4720        Message msg = Message.obtain();
4721        HashMap map = new HashMap();
4722        msg.what = SHOW_NOT_RESPONDING_MSG;
4723        msg.obj = map;
4724        map.put("app", app);
4725        if (activity != null) {
4726            map.put("activity", activity);
4727        }
4728
4729        mHandler.sendMessage(msg);
4730        return;
4731    }
4732
4733    /**
4734     * If a stack trace file has been configured, prepare the filesystem
4735     * by creating the directory if it doesn't exist and optionally
4736     * removing the old trace file.
4737     *
4738     * @param removeExisting If set, the existing trace file will be removed.
4739     * @return Returns true if the trace file preparations succeeded
4740     */
4741    public static boolean prepareTraceFile(boolean removeExisting) {
4742        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4743        boolean fileReady = false;
4744        if (!TextUtils.isEmpty(tracesPath)) {
4745            File f = new File(tracesPath);
4746            if (!f.exists()) {
4747                // Ensure the enclosing directory exists
4748                File dir = f.getParentFile();
4749                if (!dir.exists()) {
4750                    fileReady = dir.mkdirs();
4751                    FileUtils.setPermissions(dir.getAbsolutePath(),
4752                            FileUtils.S_IRWXU | FileUtils.S_IRWXG | FileUtils.S_IXOTH, -1, -1);
4753                } else if (dir.isDirectory()) {
4754                    fileReady = true;
4755                }
4756            } else if (removeExisting) {
4757                // Remove the previous traces file, so we don't fill the disk.
4758                // The VM will recreate it
4759                Log.i(TAG, "Removing old ANR trace file from " + tracesPath);
4760                fileReady = f.delete();
4761            }
4762
4763            if (removeExisting) {
4764                try {
4765                    f.createNewFile();
4766                    FileUtils.setPermissions(f.getAbsolutePath(),
4767                            FileUtils.S_IRWXU | FileUtils.S_IRWXG
4768                            | FileUtils.S_IWOTH | FileUtils.S_IROTH, -1, -1);
4769                    fileReady = true;
4770                } catch (IOException e) {
4771                    Log.w(TAG, "Unable to make ANR traces file", e);
4772                }
4773            }
4774        }
4775
4776        return fileReady;
4777    }
4778
4779
4780    private final void decPersistentCountLocked(ProcessRecord app)
4781    {
4782        app.persistentActivities--;
4783        if (app.persistentActivities > 0) {
4784            // Still more of 'em...
4785            return;
4786        }
4787        if (app.persistent) {
4788            // Ah, but the application itself is persistent.  Whatever!
4789            return;
4790        }
4791
4792        // App is no longer persistent...  make sure it and the ones
4793        // following it in the LRU list have the correc oom_adj.
4794        updateOomAdjLocked();
4795    }
4796
4797    public void setPersistent(IBinder token, boolean isPersistent) {
4798        if (checkCallingPermission(android.Manifest.permission.PERSISTENT_ACTIVITY)
4799                != PackageManager.PERMISSION_GRANTED) {
4800            String msg = "Permission Denial: setPersistent() from pid="
4801                    + Binder.getCallingPid()
4802                    + ", uid=" + Binder.getCallingUid()
4803                    + " requires " + android.Manifest.permission.PERSISTENT_ACTIVITY;
4804            Log.w(TAG, msg);
4805            throw new SecurityException(msg);
4806        }
4807
4808        synchronized(this) {
4809            int index = indexOfTokenLocked(token);
4810            if (index < 0) {
4811                return;
4812            }
4813            HistoryRecord r = (HistoryRecord)mHistory.get(index);
4814            ProcessRecord app = r.app;
4815
4816            if (localLOGV) Log.v(
4817                TAG, "Setting persistence " + isPersistent + ": " + r);
4818
4819            if (isPersistent) {
4820                if (r.persistent) {
4821                    // Okay okay, I heard you already!
4822                    if (localLOGV) Log.v(TAG, "Already persistent!");
4823                    return;
4824                }
4825                r.persistent = true;
4826                app.persistentActivities++;
4827                if (localLOGV) Log.v(TAG, "Num persistent now: " + app.persistentActivities);
4828                if (app.persistentActivities > 1) {
4829                    // We aren't the first...
4830                    if (localLOGV) Log.v(TAG, "Not the first!");
4831                    return;
4832                }
4833                if (app.persistent) {
4834                    // This would be redundant.
4835                    if (localLOGV) Log.v(TAG, "App is persistent!");
4836                    return;
4837                }
4838
4839                // App is now persistent...  make sure it and the ones
4840                // following it now have the correct oom_adj.
4841                final long origId = Binder.clearCallingIdentity();
4842                updateOomAdjLocked();
4843                Binder.restoreCallingIdentity(origId);
4844
4845            } else {
4846                if (!r.persistent) {
4847                    // Okay okay, I heard you already!
4848                    return;
4849                }
4850                r.persistent = false;
4851                final long origId = Binder.clearCallingIdentity();
4852                decPersistentCountLocked(app);
4853                Binder.restoreCallingIdentity(origId);
4854
4855            }
4856        }
4857    }
4858
4859    public boolean clearApplicationUserData(final String packageName,
4860            final IPackageDataObserver observer) {
4861        int uid = Binder.getCallingUid();
4862        int pid = Binder.getCallingPid();
4863        long callingId = Binder.clearCallingIdentity();
4864        try {
4865            IPackageManager pm = ActivityThread.getPackageManager();
4866            int pkgUid = -1;
4867            synchronized(this) {
4868                try {
4869                    pkgUid = pm.getPackageUid(packageName);
4870                } catch (RemoteException e) {
4871                }
4872                if (pkgUid == -1) {
4873                    Log.w(TAG, "Invalid packageName:" + packageName);
4874                    return false;
4875                }
4876                if (uid == pkgUid || checkComponentPermission(
4877                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4878                        pid, uid, -1)
4879                        == PackageManager.PERMISSION_GRANTED) {
4880                    restartPackageLocked(packageName, pkgUid);
4881                } else {
4882                    throw new SecurityException(pid+" does not have permission:"+
4883                            android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" +
4884                                    "for process:"+packageName);
4885                }
4886            }
4887
4888            try {
4889                //clear application user data
4890                pm.clearApplicationUserData(packageName, observer);
4891                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4892                        Uri.fromParts("package", packageName, null));
4893                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4894                broadcastIntentLocked(null, null, intent,
4895                        null, null, 0, null, null, null,
4896                        false, false, MY_PID, Process.SYSTEM_UID);
4897            } catch (RemoteException e) {
4898            }
4899        } finally {
4900            Binder.restoreCallingIdentity(callingId);
4901        }
4902        return true;
4903    }
4904
4905    public void restartPackage(final String packageName) {
4906        if (checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4907                != PackageManager.PERMISSION_GRANTED) {
4908            String msg = "Permission Denial: restartPackage() from pid="
4909                    + Binder.getCallingPid()
4910                    + ", uid=" + Binder.getCallingUid()
4911                    + " requires " + android.Manifest.permission.RESTART_PACKAGES;
4912            Log.w(TAG, msg);
4913            throw new SecurityException(msg);
4914        }
4915
4916        long callingId = Binder.clearCallingIdentity();
4917        try {
4918            IPackageManager pm = ActivityThread.getPackageManager();
4919            int pkgUid = -1;
4920            synchronized(this) {
4921                try {
4922                    pkgUid = pm.getPackageUid(packageName);
4923                } catch (RemoteException e) {
4924                }
4925                if (pkgUid == -1) {
4926                    Log.w(TAG, "Invalid packageName: " + packageName);
4927                    return;
4928                }
4929                restartPackageLocked(packageName, pkgUid);
4930            }
4931        } finally {
4932            Binder.restoreCallingIdentity(callingId);
4933        }
4934    }
4935
4936    /*
4937     * The pkg name and uid have to be specified.
4938     * @see android.app.IActivityManager#killApplicationWithUid(java.lang.String, int)
4939     */
4940    public void killApplicationWithUid(String pkg, int uid) {
4941        if (pkg == null) {
4942            return;
4943        }
4944        // Make sure the uid is valid.
4945        if (uid < 0) {
4946            Log.w(TAG, "Invalid uid specified for pkg : " + pkg);
4947            return;
4948        }
4949        int callerUid = Binder.getCallingUid();
4950        // Only the system server can kill an application
4951        if (callerUid == Process.SYSTEM_UID) {
4952            // Post an aysnc message to kill the application
4953            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4954            msg.arg1 = uid;
4955            msg.arg2 = 0;
4956            msg.obj = pkg;
4957            mHandler.sendMessage(msg);
4958        } else {
4959            throw new SecurityException(callerUid + " cannot kill pkg: " +
4960                    pkg);
4961        }
4962    }
4963
4964    public void closeSystemDialogs(String reason) {
4965        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4966        if (reason != null) {
4967            intent.putExtra("reason", reason);
4968        }
4969
4970        final int uid = Binder.getCallingUid();
4971        final long origId = Binder.clearCallingIdentity();
4972        synchronized (this) {
4973            int i = mWatchers.beginBroadcast();
4974            while (i > 0) {
4975                i--;
4976                IActivityWatcher w = mWatchers.getBroadcastItem(i);
4977                if (w != null) {
4978                    try {
4979                        w.closingSystemDialogs(reason);
4980                    } catch (RemoteException e) {
4981                    }
4982                }
4983            }
4984            mWatchers.finishBroadcast();
4985
4986            mWindowManager.closeSystemDialogs(reason);
4987
4988            for (i=mHistory.size()-1; i>=0; i--) {
4989                HistoryRecord r = (HistoryRecord)mHistory.get(i);
4990                if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
4991                    finishActivityLocked(r, i,
4992                            Activity.RESULT_CANCELED, null, "close-sys");
4993                }
4994            }
4995
4996            broadcastIntentLocked(null, null, intent, null,
4997                    null, 0, null, null, null, false, false, -1, uid);
4998        }
4999        Binder.restoreCallingIdentity(origId);
5000    }
5001
5002    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
5003            throws RemoteException {
5004        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5005        for (int i=pids.length-1; i>=0; i--) {
5006            infos[i] = new Debug.MemoryInfo();
5007            Debug.getMemoryInfo(pids[i], infos[i]);
5008        }
5009        return infos;
5010    }
5011
5012    public void killApplicationProcess(String processName, int uid) {
5013        if (processName == null) {
5014            return;
5015        }
5016
5017        int callerUid = Binder.getCallingUid();
5018        // Only the system server can kill an application
5019        if (callerUid == Process.SYSTEM_UID) {
5020            synchronized (this) {
5021                ProcessRecord app = getProcessRecordLocked(processName, uid);
5022                if (app != null) {
5023                    try {
5024                        app.thread.scheduleSuicide();
5025                    } catch (RemoteException e) {
5026                        // If the other end already died, then our work here is done.
5027                    }
5028                } else {
5029                    Log.w(TAG, "Process/uid not found attempting kill of "
5030                            + processName + " / " + uid);
5031                }
5032            }
5033        } else {
5034            throw new SecurityException(callerUid + " cannot kill app process: " +
5035                    processName);
5036        }
5037    }
5038
5039    private void restartPackageLocked(final String packageName, int uid) {
5040        uninstallPackageLocked(packageName, uid, false);
5041        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5042                Uri.fromParts("package", packageName, null));
5043        intent.putExtra(Intent.EXTRA_UID, uid);
5044        broadcastIntentLocked(null, null, intent,
5045                null, null, 0, null, null, null,
5046                false, false, MY_PID, Process.SYSTEM_UID);
5047    }
5048
5049    private final void uninstallPackageLocked(String name, int uid,
5050            boolean callerWillRestart) {
5051        if (Config.LOGD) Log.d(TAG, "Uninstalling process " + name);
5052
5053        int i, N;
5054
5055        final String procNamePrefix = name + ":";
5056        if (uid < 0) {
5057            try {
5058                uid = ActivityThread.getPackageManager().getPackageUid(name);
5059            } catch (RemoteException e) {
5060            }
5061        }
5062
5063        Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator();
5064        while (badApps.hasNext()) {
5065            SparseArray<Long> ba = badApps.next();
5066            if (ba.get(uid) != null) {
5067                badApps.remove();
5068            }
5069        }
5070
5071        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5072
5073        // Remove all processes this package may have touched: all with the
5074        // same UID (except for the system or root user), and all whose name
5075        // matches the package name.
5076        for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
5077            final int NA = apps.size();
5078            for (int ia=0; ia<NA; ia++) {
5079                ProcessRecord app = apps.valueAt(ia);
5080                if (app.removed) {
5081                    procs.add(app);
5082                } else if ((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid)
5083                        || app.processName.equals(name)
5084                        || app.processName.startsWith(procNamePrefix)) {
5085                    app.removed = true;
5086                    procs.add(app);
5087                }
5088            }
5089        }
5090
5091        N = procs.size();
5092        for (i=0; i<N; i++) {
5093            removeProcessLocked(procs.get(i), callerWillRestart);
5094        }
5095
5096        for (i=mHistory.size()-1; i>=0; i--) {
5097            HistoryRecord r = (HistoryRecord)mHistory.get(i);
5098            if (r.packageName.equals(name)) {
5099                if (Config.LOGD) Log.d(
5100                    TAG, "  Force finishing activity "
5101                    + r.intent.getComponent().flattenToShortString());
5102                if (r.app != null) {
5103                    r.app.removed = true;
5104                }
5105                r.app = null;
5106                finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "uninstall");
5107            }
5108        }
5109
5110        ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
5111        for (ServiceRecord service : mServices.values()) {
5112            if (service.packageName.equals(name)) {
5113                if (service.app != null) {
5114                    service.app.removed = true;
5115                }
5116                service.app = null;
5117                services.add(service);
5118            }
5119        }
5120
5121        N = services.size();
5122        for (i=0; i<N; i++) {
5123            bringDownServiceLocked(services.get(i), true);
5124        }
5125
5126        resumeTopActivityLocked(null);
5127    }
5128
5129    private final boolean removeProcessLocked(ProcessRecord app, boolean callerWillRestart) {
5130        final String name = app.processName;
5131        final int uid = app.info.uid;
5132        if (Config.LOGD) Log.d(
5133            TAG, "Force removing process " + app + " (" + name
5134            + "/" + uid + ")");
5135
5136        mProcessNames.remove(name, uid);
5137        boolean needRestart = false;
5138        if (app.pid > 0 && app.pid != MY_PID) {
5139            int pid = app.pid;
5140            synchronized (mPidsSelfLocked) {
5141                mPidsSelfLocked.remove(pid);
5142                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5143            }
5144            handleAppDiedLocked(app, true);
5145            mLRUProcesses.remove(app);
5146            Process.killProcess(pid);
5147
5148            if (app.persistent) {
5149                if (!callerWillRestart) {
5150                    addAppLocked(app.info);
5151                } else {
5152                    needRestart = true;
5153                }
5154            }
5155        } else {
5156            mRemovedProcesses.add(app);
5157        }
5158
5159        return needRestart;
5160    }
5161
5162    private final void processStartTimedOutLocked(ProcessRecord app) {
5163        final int pid = app.pid;
5164        boolean gone = false;
5165        synchronized (mPidsSelfLocked) {
5166            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5167            if (knownApp != null && knownApp.thread == null) {
5168                mPidsSelfLocked.remove(pid);
5169                gone = true;
5170            }
5171        }
5172
5173        if (gone) {
5174            Log.w(TAG, "Process " + app + " failed to attach");
5175            mProcessNames.remove(app.processName, app.info.uid);
5176            Process.killProcess(pid);
5177            if (mPendingBroadcast != null && mPendingBroadcast.curApp.pid == pid) {
5178                Log.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5179                mPendingBroadcast = null;
5180                scheduleBroadcastsLocked();
5181            }
5182            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5183                Log.w(TAG, "Unattached app died before backup, skipping");
5184                try {
5185                    IBackupManager bm = IBackupManager.Stub.asInterface(
5186                            ServiceManager.getService(Context.BACKUP_SERVICE));
5187                    bm.agentDisconnected(app.info.packageName);
5188                } catch (RemoteException e) {
5189                    // Can't happen; the backup manager is local
5190                }
5191            }
5192        } else {
5193            Log.w(TAG, "Spurious process start timeout - pid not known for " + app);
5194        }
5195    }
5196
5197    private final boolean attachApplicationLocked(IApplicationThread thread,
5198            int pid) {
5199
5200        // Find the application record that is being attached...  either via
5201        // the pid if we are running in multiple processes, or just pull the
5202        // next app record if we are emulating process with anonymous threads.
5203        ProcessRecord app;
5204        if (pid != MY_PID && pid >= 0) {
5205            synchronized (mPidsSelfLocked) {
5206                app = mPidsSelfLocked.get(pid);
5207            }
5208        } else if (mStartingProcesses.size() > 0) {
5209            app = mStartingProcesses.remove(0);
5210            app.setPid(pid);
5211        } else {
5212            app = null;
5213        }
5214
5215        if (app == null) {
5216            Log.w(TAG, "No pending application record for pid " + pid
5217                    + " (IApplicationThread " + thread + "); dropping process");
5218            EventLog.writeEvent(LOG_AM_DROP_PROCESS, pid);
5219            if (pid > 0 && pid != MY_PID) {
5220                Process.killProcess(pid);
5221            } else {
5222                try {
5223                    thread.scheduleExit();
5224                } catch (Exception e) {
5225                    // Ignore exceptions.
5226                }
5227            }
5228            return false;
5229        }
5230
5231        // If this application record is still attached to a previous
5232        // process, clean it up now.
5233        if (app.thread != null) {
5234            handleAppDiedLocked(app, true);
5235        }
5236
5237        // Tell the process all about itself.
5238
5239        if (localLOGV) Log.v(
5240                TAG, "Binding process pid " + pid + " to record " + app);
5241
5242        String processName = app.processName;
5243        try {
5244            thread.asBinder().linkToDeath(new AppDeathRecipient(
5245                    app, pid, thread), 0);
5246        } catch (RemoteException e) {
5247            app.resetPackageList();
5248            startProcessLocked(app, "link fail", processName);
5249            return false;
5250        }
5251
5252        EventLog.writeEvent(LOG_AM_PROCESS_BOUND, app.pid, app.processName);
5253
5254        app.thread = thread;
5255        app.curAdj = app.setAdj = -100;
5256        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5257        app.forcingToForeground = null;
5258        app.foregroundServices = false;
5259        app.debugging = false;
5260
5261        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5262
5263        boolean normalMode = mSystemReady || isAllowedWhileBooting(app.info);
5264        List providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5265
5266        if (!normalMode) {
5267            Log.i(TAG, "Launching preboot mode app: " + app);
5268        }
5269
5270        if (localLOGV) Log.v(
5271            TAG, "New app record " + app
5272            + " thread=" + thread.asBinder() + " pid=" + pid);
5273        try {
5274            int testMode = IApplicationThread.DEBUG_OFF;
5275            if (mDebugApp != null && mDebugApp.equals(processName)) {
5276                testMode = mWaitForDebugger
5277                    ? IApplicationThread.DEBUG_WAIT
5278                    : IApplicationThread.DEBUG_ON;
5279                app.debugging = true;
5280                if (mDebugTransient) {
5281                    mDebugApp = mOrigDebugApp;
5282                    mWaitForDebugger = mOrigWaitForDebugger;
5283                }
5284            }
5285
5286            // If the app is being launched for restore or full backup, set it up specially
5287            boolean isRestrictedBackupMode = false;
5288            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5289                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5290                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5291            }
5292
5293            ensurePackageDexOpt(app.instrumentationInfo != null
5294                    ? app.instrumentationInfo.packageName
5295                    : app.info.packageName);
5296            if (app.instrumentationClass != null) {
5297                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5298            }
5299            if (DEBUG_CONFIGURATION) Log.v(TAG, "Binding proc "
5300                    + processName + " with config " + mConfiguration);
5301            thread.bindApplication(processName, app.instrumentationInfo != null
5302                    ? app.instrumentationInfo : app.info, providers,
5303                    app.instrumentationClass, app.instrumentationProfileFile,
5304                    app.instrumentationArguments, app.instrumentationWatcher, testMode,
5305                    isRestrictedBackupMode || !normalMode,
5306                    mConfiguration, getCommonServicesLocked());
5307            updateLRUListLocked(app, false);
5308            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5309        } catch (Exception e) {
5310            // todo: Yikes!  What should we do?  For now we will try to
5311            // start another process, but that could easily get us in
5312            // an infinite loop of restarting processes...
5313            Log.w(TAG, "Exception thrown during bind!", e);
5314
5315            app.resetPackageList();
5316            startProcessLocked(app, "bind fail", processName);
5317            return false;
5318        }
5319
5320        // Remove this record from the list of starting applications.
5321        mPersistentStartingProcesses.remove(app);
5322        mProcessesOnHold.remove(app);
5323
5324        boolean badApp = false;
5325        boolean didSomething = false;
5326
5327        // See if the top visible activity is waiting to run in this process...
5328        HistoryRecord hr = topRunningActivityLocked(null);
5329        if (hr != null) {
5330            if (hr.app == null && app.info.uid == hr.info.applicationInfo.uid
5331                    && processName.equals(hr.processName)) {
5332                try {
5333                    if (realStartActivityLocked(hr, app, true, true)) {
5334                        didSomething = true;
5335                    }
5336                } catch (Exception e) {
5337                    Log.w(TAG, "Exception in new application when starting activity "
5338                          + hr.intent.getComponent().flattenToShortString(), e);
5339                    badApp = true;
5340                }
5341            } else {
5342                ensureActivitiesVisibleLocked(hr, null, processName, 0);
5343            }
5344        }
5345
5346        // Find any services that should be running in this process...
5347        if (!badApp && mPendingServices.size() > 0) {
5348            ServiceRecord sr = null;
5349            try {
5350                for (int i=0; i<mPendingServices.size(); i++) {
5351                    sr = mPendingServices.get(i);
5352                    if (app.info.uid != sr.appInfo.uid
5353                            || !processName.equals(sr.processName)) {
5354                        continue;
5355                    }
5356
5357                    mPendingServices.remove(i);
5358                    i--;
5359                    realStartServiceLocked(sr, app);
5360                    didSomething = true;
5361                }
5362            } catch (Exception e) {
5363                Log.w(TAG, "Exception in new application when starting service "
5364                      + sr.shortName, e);
5365                badApp = true;
5366            }
5367        }
5368
5369        // Check if the next broadcast receiver is in this process...
5370        BroadcastRecord br = mPendingBroadcast;
5371        if (!badApp && br != null && br.curApp == app) {
5372            try {
5373                mPendingBroadcast = null;
5374                processCurBroadcastLocked(br, app);
5375                didSomething = true;
5376            } catch (Exception e) {
5377                Log.w(TAG, "Exception in new application when starting receiver "
5378                      + br.curComponent.flattenToShortString(), e);
5379                badApp = true;
5380                logBroadcastReceiverDiscard(br);
5381                finishReceiverLocked(br.receiver, br.resultCode, br.resultData,
5382                        br.resultExtras, br.resultAbort, true);
5383                scheduleBroadcastsLocked();
5384            }
5385        }
5386
5387        // Check whether the next backup agent is in this process...
5388        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.info.uid) {
5389            if (DEBUG_BACKUP) Log.v(TAG, "New app is backup target, launching agent for " + app);
5390            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5391            try {
5392                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, mBackupTarget.backupMode);
5393            } catch (Exception e) {
5394                Log.w(TAG, "Exception scheduling backup agent creation: ");
5395                e.printStackTrace();
5396            }
5397        }
5398
5399        if (badApp) {
5400            // todo: Also need to kill application to deal with all
5401            // kinds of exceptions.
5402            handleAppDiedLocked(app, false);
5403            return false;
5404        }
5405
5406        if (!didSomething) {
5407            updateOomAdjLocked();
5408        }
5409
5410        return true;
5411    }
5412
5413    public final void attachApplication(IApplicationThread thread) {
5414        synchronized (this) {
5415            int callingPid = Binder.getCallingPid();
5416            final long origId = Binder.clearCallingIdentity();
5417            attachApplicationLocked(thread, callingPid);
5418            Binder.restoreCallingIdentity(origId);
5419        }
5420    }
5421
5422    public final void activityIdle(IBinder token) {
5423        final long origId = Binder.clearCallingIdentity();
5424        activityIdleInternal(token, false);
5425        Binder.restoreCallingIdentity(origId);
5426    }
5427
5428    final ArrayList<HistoryRecord> processStoppingActivitiesLocked(
5429            boolean remove) {
5430        int N = mStoppingActivities.size();
5431        if (N <= 0) return null;
5432
5433        ArrayList<HistoryRecord> stops = null;
5434
5435        final boolean nowVisible = mResumedActivity != null
5436                && mResumedActivity.nowVisible
5437                && !mResumedActivity.waitingVisible;
5438        for (int i=0; i<N; i++) {
5439            HistoryRecord s = mStoppingActivities.get(i);
5440            if (localLOGV) Log.v(TAG, "Stopping " + s + ": nowVisible="
5441                    + nowVisible + " waitingVisible=" + s.waitingVisible
5442                    + " finishing=" + s.finishing);
5443            if (s.waitingVisible && nowVisible) {
5444                mWaitingVisibleActivities.remove(s);
5445                s.waitingVisible = false;
5446                if (s.finishing) {
5447                    // If this activity is finishing, it is sitting on top of
5448                    // everyone else but we now know it is no longer needed...
5449                    // so get rid of it.  Otherwise, we need to go through the
5450                    // normal flow and hide it once we determine that it is
5451                    // hidden by the activities in front of it.
5452                    if (localLOGV) Log.v(TAG, "Before stopping, can hide: " + s);
5453                    mWindowManager.setAppVisibility(s, false);
5454                }
5455            }
5456            if (!s.waitingVisible && remove) {
5457                if (localLOGV) Log.v(TAG, "Ready to stop: " + s);
5458                if (stops == null) {
5459                    stops = new ArrayList<HistoryRecord>();
5460                }
5461                stops.add(s);
5462                mStoppingActivities.remove(i);
5463                N--;
5464                i--;
5465            }
5466        }
5467
5468        return stops;
5469    }
5470
5471    void enableScreenAfterBoot() {
5472        EventLog.writeEvent(LOG_BOOT_PROGRESS_ENABLE_SCREEN,
5473                SystemClock.uptimeMillis());
5474        mWindowManager.enableScreenAfterBoot();
5475    }
5476
5477    final void activityIdleInternal(IBinder token, boolean fromTimeout) {
5478        if (localLOGV) Log.v(TAG, "Activity idle: " + token);
5479
5480        ArrayList<HistoryRecord> stops = null;
5481        ArrayList<HistoryRecord> finishes = null;
5482        ArrayList<HistoryRecord> thumbnails = null;
5483        int NS = 0;
5484        int NF = 0;
5485        int NT = 0;
5486        IApplicationThread sendThumbnail = null;
5487        boolean booting = false;
5488        boolean enableScreen = false;
5489
5490        synchronized (this) {
5491            if (token != null) {
5492                mHandler.removeMessages(IDLE_TIMEOUT_MSG, token);
5493            }
5494
5495            // Get the activity record.
5496            int index = indexOfTokenLocked(token);
5497            if (index >= 0) {
5498                HistoryRecord r = (HistoryRecord)mHistory.get(index);
5499
5500                // No longer need to keep the device awake.
5501                if (mResumedActivity == r && mLaunchingActivity.isHeld()) {
5502                    mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
5503                    mLaunchingActivity.release();
5504                }
5505
5506                // We are now idle.  If someone is waiting for a thumbnail from
5507                // us, we can now deliver.
5508                r.idle = true;
5509                scheduleAppGcsLocked();
5510                if (r.thumbnailNeeded && r.app != null && r.app.thread != null) {
5511                    sendThumbnail = r.app.thread;
5512                    r.thumbnailNeeded = false;
5513                }
5514
5515                // If this activity is fullscreen, set up to hide those under it.
5516
5517                if (DEBUG_VISBILITY) Log.v(TAG, "Idle activity for " + r);
5518                ensureActivitiesVisibleLocked(null, 0);
5519
5520                //Log.i(TAG, "IDLE: mBooted=" + mBooted + ", fromTimeout=" + fromTimeout);
5521                if (!mBooted && !fromTimeout) {
5522                    mBooted = true;
5523                    enableScreen = true;
5524                }
5525            }
5526
5527            // Atomically retrieve all of the other things to do.
5528            stops = processStoppingActivitiesLocked(true);
5529            NS = stops != null ? stops.size() : 0;
5530            if ((NF=mFinishingActivities.size()) > 0) {
5531                finishes = new ArrayList<HistoryRecord>(mFinishingActivities);
5532                mFinishingActivities.clear();
5533            }
5534            if ((NT=mCancelledThumbnails.size()) > 0) {
5535                thumbnails = new ArrayList<HistoryRecord>(mCancelledThumbnails);
5536                mCancelledThumbnails.clear();
5537            }
5538
5539            booting = mBooting;
5540            mBooting = false;
5541        }
5542
5543        int i;
5544
5545        // Send thumbnail if requested.
5546        if (sendThumbnail != null) {
5547            try {
5548                sendThumbnail.requestThumbnail(token);
5549            } catch (Exception e) {
5550                Log.w(TAG, "Exception thrown when requesting thumbnail", e);
5551                sendPendingThumbnail(null, token, null, null, true);
5552            }
5553        }
5554
5555        // Stop any activities that are scheduled to do so but have been
5556        // waiting for the next one to start.
5557        for (i=0; i<NS; i++) {
5558            HistoryRecord r = (HistoryRecord)stops.get(i);
5559            synchronized (this) {
5560                if (r.finishing) {
5561                    finishCurrentActivityLocked(r, FINISH_IMMEDIATELY);
5562                } else {
5563                    stopActivityLocked(r);
5564                }
5565            }
5566        }
5567
5568        // Finish any activities that are scheduled to do so but have been
5569        // waiting for the next one to start.
5570        for (i=0; i<NF; i++) {
5571            HistoryRecord r = (HistoryRecord)finishes.get(i);
5572            synchronized (this) {
5573                destroyActivityLocked(r, true);
5574            }
5575        }
5576
5577        // Report back to any thumbnail receivers.
5578        for (i=0; i<NT; i++) {
5579            HistoryRecord r = (HistoryRecord)thumbnails.get(i);
5580            sendPendingThumbnail(r, null, null, null, true);
5581        }
5582
5583        if (booting) {
5584            finishBooting();
5585        }
5586
5587        trimApplications();
5588        //dump();
5589        //mWindowManager.dump();
5590
5591        if (enableScreen) {
5592            enableScreenAfterBoot();
5593        }
5594    }
5595
5596    final void finishBooting() {
5597        // Ensure that any processes we had put on hold are now started
5598        // up.
5599        final int NP = mProcessesOnHold.size();
5600        if (NP > 0) {
5601            ArrayList<ProcessRecord> procs =
5602                new ArrayList<ProcessRecord>(mProcessesOnHold);
5603            for (int ip=0; ip<NP; ip++) {
5604                this.startProcessLocked(procs.get(ip), "on-hold", null);
5605            }
5606        }
5607        if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
5608            // Tell anyone interested that we are done booting!
5609            synchronized (this) {
5610                broadcastIntentLocked(null, null,
5611                        new Intent(Intent.ACTION_BOOT_COMPLETED, null),
5612                        null, null, 0, null, null,
5613                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5614                        false, false, MY_PID, Process.SYSTEM_UID);
5615            }
5616        }
5617    }
5618
5619    final void ensureBootCompleted() {
5620        boolean booting;
5621        boolean enableScreen;
5622        synchronized (this) {
5623            booting = mBooting;
5624            mBooting = false;
5625            enableScreen = !mBooted;
5626            mBooted = true;
5627        }
5628
5629        if (booting) {
5630            finishBooting();
5631        }
5632
5633        if (enableScreen) {
5634            enableScreenAfterBoot();
5635        }
5636    }
5637
5638    public final void activityPaused(IBinder token, Bundle icicle) {
5639        // Refuse possible leaked file descriptors
5640        if (icicle != null && icicle.hasFileDescriptors()) {
5641            throw new IllegalArgumentException("File descriptors passed in Bundle");
5642        }
5643
5644        final long origId = Binder.clearCallingIdentity();
5645        activityPaused(token, icicle, false);
5646        Binder.restoreCallingIdentity(origId);
5647    }
5648
5649    final void activityPaused(IBinder token, Bundle icicle, boolean timeout) {
5650        if (DEBUG_PAUSE) Log.v(
5651            TAG, "Activity paused: token=" + token + ", icicle=" + icicle
5652            + ", timeout=" + timeout);
5653
5654        HistoryRecord r = null;
5655
5656        synchronized (this) {
5657            int index = indexOfTokenLocked(token);
5658            if (index >= 0) {
5659                r = (HistoryRecord)mHistory.get(index);
5660                if (!timeout) {
5661                    r.icicle = icicle;
5662                    r.haveState = true;
5663                }
5664                mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);
5665                if (mPausingActivity == r) {
5666                    r.state = ActivityState.PAUSED;
5667                    completePauseLocked();
5668                } else {
5669                	EventLog.writeEvent(LOG_AM_FAILED_TO_PAUSE_ACTIVITY,
5670                	        System.identityHashCode(r), r.shortComponentName,
5671                			mPausingActivity != null
5672                			    ? mPausingActivity.shortComponentName : "(none)");
5673                }
5674            }
5675        }
5676    }
5677
5678    public final void activityStopped(IBinder token, Bitmap thumbnail,
5679            CharSequence description) {
5680        if (localLOGV) Log.v(
5681            TAG, "Activity stopped: token=" + token);
5682
5683        HistoryRecord r = null;
5684
5685        final long origId = Binder.clearCallingIdentity();
5686
5687        synchronized (this) {
5688            int index = indexOfTokenLocked(token);
5689            if (index >= 0) {
5690                r = (HistoryRecord)mHistory.get(index);
5691                r.thumbnail = thumbnail;
5692                r.description = description;
5693                r.stopped = true;
5694                r.state = ActivityState.STOPPED;
5695                if (!r.finishing) {
5696                    if (r.configDestroy) {
5697                        destroyActivityLocked(r, true);
5698                        resumeTopActivityLocked(null);
5699                    }
5700                }
5701            }
5702        }
5703
5704        if (r != null) {
5705            sendPendingThumbnail(r, null, null, null, false);
5706        }
5707
5708        trimApplications();
5709
5710        Binder.restoreCallingIdentity(origId);
5711    }
5712
5713    public final void activityDestroyed(IBinder token) {
5714        if (DEBUG_SWITCH) Log.v(TAG, "ACTIVITY DESTROYED: " + token);
5715        synchronized (this) {
5716            mHandler.removeMessages(DESTROY_TIMEOUT_MSG, token);
5717
5718            int index = indexOfTokenLocked(token);
5719            if (index >= 0) {
5720                HistoryRecord r = (HistoryRecord)mHistory.get(index);
5721                if (r.state == ActivityState.DESTROYING) {
5722                    final long origId = Binder.clearCallingIdentity();
5723                    removeActivityFromHistoryLocked(r);
5724                    Binder.restoreCallingIdentity(origId);
5725                }
5726            }
5727        }
5728    }
5729
5730    public String getCallingPackage(IBinder token) {
5731        synchronized (this) {
5732            HistoryRecord r = getCallingRecordLocked(token);
5733            return r != null && r.app != null ? r.app.processName : null;
5734        }
5735    }
5736
5737    public ComponentName getCallingActivity(IBinder token) {
5738        synchronized (this) {
5739            HistoryRecord r = getCallingRecordLocked(token);
5740            return r != null ? r.intent.getComponent() : null;
5741        }
5742    }
5743
5744    private HistoryRecord getCallingRecordLocked(IBinder token) {
5745        int index = indexOfTokenLocked(token);
5746        if (index >= 0) {
5747            HistoryRecord r = (HistoryRecord)mHistory.get(index);
5748            if (r != null) {
5749                return r.resultTo;
5750            }
5751        }
5752        return null;
5753    }
5754
5755    public ComponentName getActivityClassForToken(IBinder token) {
5756        synchronized(this) {
5757            int index = indexOfTokenLocked(token);
5758            if (index >= 0) {
5759                HistoryRecord r = (HistoryRecord)mHistory.get(index);
5760                return r.intent.getComponent();
5761            }
5762            return null;
5763        }
5764    }
5765
5766    public String getPackageForToken(IBinder token) {
5767        synchronized(this) {
5768            int index = indexOfTokenLocked(token);
5769            if (index >= 0) {
5770                HistoryRecord r = (HistoryRecord)mHistory.get(index);
5771                return r.packageName;
5772            }
5773            return null;
5774        }
5775    }
5776
5777    public IIntentSender getIntentSender(int type,
5778            String packageName, IBinder token, String resultWho,
5779            int requestCode, Intent intent, String resolvedType, int flags) {
5780        // Refuse possible leaked file descriptors
5781        if (intent != null && intent.hasFileDescriptors() == true) {
5782            throw new IllegalArgumentException("File descriptors passed in Intent");
5783        }
5784
5785        if (type == INTENT_SENDER_BROADCAST) {
5786            if ((intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5787                throw new IllegalArgumentException(
5788                        "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5789            }
5790        }
5791
5792        synchronized(this) {
5793            int callingUid = Binder.getCallingUid();
5794            try {
5795                if (callingUid != 0 && callingUid != Process.SYSTEM_UID &&
5796                        Process.supportsProcesses()) {
5797                    int uid = ActivityThread.getPackageManager()
5798                            .getPackageUid(packageName);
5799                    if (uid != Binder.getCallingUid()) {
5800                        String msg = "Permission Denial: getIntentSender() from pid="
5801                            + Binder.getCallingPid()
5802                            + ", uid=" + Binder.getCallingUid()
5803                            + ", (need uid=" + uid + ")"
5804                            + " is not allowed to send as package " + packageName;
5805                        Log.w(TAG, msg);
5806                        throw new SecurityException(msg);
5807                    }
5808                }
5809            } catch (RemoteException e) {
5810                throw new SecurityException(e);
5811            }
5812            HistoryRecord activity = null;
5813            if (type == INTENT_SENDER_ACTIVITY_RESULT) {
5814                int index = indexOfTokenLocked(token);
5815                if (index < 0) {
5816                    return null;
5817                }
5818                activity = (HistoryRecord)mHistory.get(index);
5819                if (activity.finishing) {
5820                    return null;
5821                }
5822            }
5823
5824            final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5825            final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5826            final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5827            flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5828                    |PendingIntent.FLAG_UPDATE_CURRENT);
5829
5830            PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5831                    type, packageName, activity, resultWho,
5832                    requestCode, intent, resolvedType, flags);
5833            WeakReference<PendingIntentRecord> ref;
5834            ref = mIntentSenderRecords.get(key);
5835            PendingIntentRecord rec = ref != null ? ref.get() : null;
5836            if (rec != null) {
5837                if (!cancelCurrent) {
5838                    if (updateCurrent) {
5839                        rec.key.requestIntent.replaceExtras(intent);
5840                    }
5841                    return rec;
5842                }
5843                rec.canceled = true;
5844                mIntentSenderRecords.remove(key);
5845            }
5846            if (noCreate) {
5847                return rec;
5848            }
5849            rec = new PendingIntentRecord(this, key, callingUid);
5850            mIntentSenderRecords.put(key, rec.ref);
5851            if (type == INTENT_SENDER_ACTIVITY_RESULT) {
5852                if (activity.pendingResults == null) {
5853                    activity.pendingResults
5854                            = new HashSet<WeakReference<PendingIntentRecord>>();
5855                }
5856                activity.pendingResults.add(rec.ref);
5857            }
5858            return rec;
5859        }
5860    }
5861
5862    public void cancelIntentSender(IIntentSender sender) {
5863        if (!(sender instanceof PendingIntentRecord)) {
5864            return;
5865        }
5866        synchronized(this) {
5867            PendingIntentRecord rec = (PendingIntentRecord)sender;
5868            try {
5869                int uid = ActivityThread.getPackageManager()
5870                        .getPackageUid(rec.key.packageName);
5871                if (uid != Binder.getCallingUid()) {
5872                    String msg = "Permission Denial: cancelIntentSender() from pid="
5873                        + Binder.getCallingPid()
5874                        + ", uid=" + Binder.getCallingUid()
5875                        + " is not allowed to cancel packges "
5876                        + rec.key.packageName;
5877                    Log.w(TAG, msg);
5878                    throw new SecurityException(msg);
5879                }
5880            } catch (RemoteException e) {
5881                throw new SecurityException(e);
5882            }
5883            cancelIntentSenderLocked(rec, true);
5884        }
5885    }
5886
5887    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5888        rec.canceled = true;
5889        mIntentSenderRecords.remove(rec.key);
5890        if (cleanActivity && rec.key.activity != null) {
5891            rec.key.activity.pendingResults.remove(rec.ref);
5892        }
5893    }
5894
5895    public String getPackageForIntentSender(IIntentSender pendingResult) {
5896        if (!(pendingResult instanceof PendingIntentRecord)) {
5897            return null;
5898        }
5899        synchronized(this) {
5900            try {
5901                PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5902                return res.key.packageName;
5903            } catch (ClassCastException e) {
5904            }
5905        }
5906        return null;
5907    }
5908
5909    public void setProcessLimit(int max) {
5910        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5911                "setProcessLimit()");
5912        mProcessLimit = max;
5913    }
5914
5915    public int getProcessLimit() {
5916        return mProcessLimit;
5917    }
5918
5919    void foregroundTokenDied(ForegroundToken token) {
5920        synchronized (ActivityManagerService.this) {
5921            synchronized (mPidsSelfLocked) {
5922                ForegroundToken cur
5923                    = mForegroundProcesses.get(token.pid);
5924                if (cur != token) {
5925                    return;
5926                }
5927                mForegroundProcesses.remove(token.pid);
5928                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
5929                if (pr == null) {
5930                    return;
5931                }
5932                pr.forcingToForeground = null;
5933                pr.foregroundServices = false;
5934            }
5935            updateOomAdjLocked();
5936        }
5937    }
5938
5939    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
5940        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5941                "setProcessForeground()");
5942        synchronized(this) {
5943            boolean changed = false;
5944
5945            synchronized (mPidsSelfLocked) {
5946                ProcessRecord pr = mPidsSelfLocked.get(pid);
5947                if (pr == null) {
5948                    Log.w(TAG, "setProcessForeground called on unknown pid: " + pid);
5949                    return;
5950                }
5951                ForegroundToken oldToken = mForegroundProcesses.get(pid);
5952                if (oldToken != null) {
5953                    oldToken.token.unlinkToDeath(oldToken, 0);
5954                    mForegroundProcesses.remove(pid);
5955                    pr.forcingToForeground = null;
5956                    changed = true;
5957                }
5958                if (isForeground && token != null) {
5959                    ForegroundToken newToken = new ForegroundToken() {
5960                        public void binderDied() {
5961                            foregroundTokenDied(this);
5962                        }
5963                    };
5964                    newToken.pid = pid;
5965                    newToken.token = token;
5966                    try {
5967                        token.linkToDeath(newToken, 0);
5968                        mForegroundProcesses.put(pid, newToken);
5969                        pr.forcingToForeground = token;
5970                        changed = true;
5971                    } catch (RemoteException e) {
5972                        // If the process died while doing this, we will later
5973                        // do the cleanup with the process death link.
5974                    }
5975                }
5976            }
5977
5978            if (changed) {
5979                updateOomAdjLocked();
5980            }
5981        }
5982    }
5983
5984    // =========================================================
5985    // PERMISSIONS
5986    // =========================================================
5987
5988    static class PermissionController extends IPermissionController.Stub {
5989        ActivityManagerService mActivityManagerService;
5990        PermissionController(ActivityManagerService activityManagerService) {
5991            mActivityManagerService = activityManagerService;
5992        }
5993
5994        public boolean checkPermission(String permission, int pid, int uid) {
5995            return mActivityManagerService.checkPermission(permission, pid,
5996                    uid) == PackageManager.PERMISSION_GRANTED;
5997        }
5998    }
5999
6000    /**
6001     * This can be called with or without the global lock held.
6002     */
6003    int checkComponentPermission(String permission, int pid, int uid,
6004            int reqUid) {
6005        // We might be performing an operation on behalf of an indirect binder
6006        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6007        // client identity accordingly before proceeding.
6008        Identity tlsIdentity = sCallerIdentity.get();
6009        if (tlsIdentity != null) {
6010            Log.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6011                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6012            uid = tlsIdentity.uid;
6013            pid = tlsIdentity.pid;
6014        }
6015
6016        // Root, system server and our own process get to do everything.
6017        if (uid == 0 || uid == Process.SYSTEM_UID || pid == MY_PID ||
6018            !Process.supportsProcesses()) {
6019            return PackageManager.PERMISSION_GRANTED;
6020        }
6021        // If the target requires a specific UID, always fail for others.
6022        if (reqUid >= 0 && uid != reqUid) {
6023            return PackageManager.PERMISSION_DENIED;
6024        }
6025        if (permission == null) {
6026            return PackageManager.PERMISSION_GRANTED;
6027        }
6028        try {
6029            return ActivityThread.getPackageManager()
6030                    .checkUidPermission(permission, uid);
6031        } catch (RemoteException e) {
6032            // Should never happen, but if it does... deny!
6033            Log.e(TAG, "PackageManager is dead?!?", e);
6034        }
6035        return PackageManager.PERMISSION_DENIED;
6036    }
6037
6038    /**
6039     * As the only public entry point for permissions checking, this method
6040     * can enforce the semantic that requesting a check on a null global
6041     * permission is automatically denied.  (Internally a null permission
6042     * string is used when calling {@link #checkComponentPermission} in cases
6043     * when only uid-based security is needed.)
6044     *
6045     * This can be called with or without the global lock held.
6046     */
6047    public int checkPermission(String permission, int pid, int uid) {
6048        if (permission == null) {
6049            return PackageManager.PERMISSION_DENIED;
6050        }
6051        return checkComponentPermission(permission, pid, uid, -1);
6052    }
6053
6054    /**
6055     * Binder IPC calls go through the public entry point.
6056     * This can be called with or without the global lock held.
6057     */
6058    int checkCallingPermission(String permission) {
6059        return checkPermission(permission,
6060                Binder.getCallingPid(),
6061                Binder.getCallingUid());
6062    }
6063
6064    /**
6065     * This can be called with or without the global lock held.
6066     */
6067    void enforceCallingPermission(String permission, String func) {
6068        if (checkCallingPermission(permission)
6069                == PackageManager.PERMISSION_GRANTED) {
6070            return;
6071        }
6072
6073        String msg = "Permission Denial: " + func + " from pid="
6074                + Binder.getCallingPid()
6075                + ", uid=" + Binder.getCallingUid()
6076                + " requires " + permission;
6077        Log.w(TAG, msg);
6078        throw new SecurityException(msg);
6079    }
6080
6081    private final boolean checkHoldingPermissionsLocked(IPackageManager pm,
6082            ProviderInfo pi, int uid, int modeFlags) {
6083        try {
6084            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6085                if ((pi.readPermission != null) &&
6086                        (pm.checkUidPermission(pi.readPermission, uid)
6087                                != PackageManager.PERMISSION_GRANTED)) {
6088                    return false;
6089                }
6090            }
6091            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6092                if ((pi.writePermission != null) &&
6093                        (pm.checkUidPermission(pi.writePermission, uid)
6094                                != PackageManager.PERMISSION_GRANTED)) {
6095                    return false;
6096                }
6097            }
6098            return true;
6099        } catch (RemoteException e) {
6100            return false;
6101        }
6102    }
6103
6104    private final boolean checkUriPermissionLocked(Uri uri, int uid,
6105            int modeFlags) {
6106        // Root gets to do everything.
6107        if (uid == 0 || !Process.supportsProcesses()) {
6108            return true;
6109        }
6110        HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6111        if (perms == null) return false;
6112        UriPermission perm = perms.get(uri);
6113        if (perm == null) return false;
6114        return (modeFlags&perm.modeFlags) == modeFlags;
6115    }
6116
6117    public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
6118        // Another redirected-binder-call permissions check as in
6119        // {@link checkComponentPermission}.
6120        Identity tlsIdentity = sCallerIdentity.get();
6121        if (tlsIdentity != null) {
6122            uid = tlsIdentity.uid;
6123            pid = tlsIdentity.pid;
6124        }
6125
6126        // Our own process gets to do everything.
6127        if (pid == MY_PID) {
6128            return PackageManager.PERMISSION_GRANTED;
6129        }
6130        synchronized(this) {
6131            return checkUriPermissionLocked(uri, uid, modeFlags)
6132                    ? PackageManager.PERMISSION_GRANTED
6133                    : PackageManager.PERMISSION_DENIED;
6134        }
6135    }
6136
6137    private void grantUriPermissionLocked(int callingUid,
6138            String targetPkg, Uri uri, int modeFlags, HistoryRecord activity) {
6139        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
6140                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6141        if (modeFlags == 0) {
6142            return;
6143        }
6144
6145        final IPackageManager pm = ActivityThread.getPackageManager();
6146
6147        // If this is not a content: uri, we can't do anything with it.
6148        if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
6149            return;
6150        }
6151
6152        String name = uri.getAuthority();
6153        ProviderInfo pi = null;
6154        ContentProviderRecord cpr
6155                = (ContentProviderRecord)mProvidersByName.get(name);
6156        if (cpr != null) {
6157            pi = cpr.info;
6158        } else {
6159            try {
6160                pi = pm.resolveContentProvider(name,
6161                        PackageManager.GET_URI_PERMISSION_PATTERNS);
6162            } catch (RemoteException ex) {
6163            }
6164        }
6165        if (pi == null) {
6166            Log.w(TAG, "No content provider found for: " + name);
6167            return;
6168        }
6169
6170        int targetUid;
6171        try {
6172            targetUid = pm.getPackageUid(targetPkg);
6173            if (targetUid < 0) {
6174                return;
6175            }
6176        } catch (RemoteException ex) {
6177            return;
6178        }
6179
6180        // First...  does the target actually need this permission?
6181        if (checkHoldingPermissionsLocked(pm, pi, targetUid, modeFlags)) {
6182            // No need to grant the target this permission.
6183            return;
6184        }
6185
6186        // Second...  maybe someone else has already granted the
6187        // permission?
6188        if (checkUriPermissionLocked(uri, targetUid, modeFlags)) {
6189            // No need to grant the target this permission.
6190            return;
6191        }
6192
6193        // Third...  is the provider allowing granting of URI permissions?
6194        if (!pi.grantUriPermissions) {
6195            throw new SecurityException("Provider " + pi.packageName
6196                    + "/" + pi.name
6197                    + " does not allow granting of Uri permissions (uri "
6198                    + uri + ")");
6199        }
6200        if (pi.uriPermissionPatterns != null) {
6201            final int N = pi.uriPermissionPatterns.length;
6202            boolean allowed = false;
6203            for (int i=0; i<N; i++) {
6204                if (pi.uriPermissionPatterns[i] != null
6205                        && pi.uriPermissionPatterns[i].match(uri.getPath())) {
6206                    allowed = true;
6207                    break;
6208                }
6209            }
6210            if (!allowed) {
6211                throw new SecurityException("Provider " + pi.packageName
6212                        + "/" + pi.name
6213                        + " does not allow granting of permission to path of Uri "
6214                        + uri);
6215            }
6216        }
6217
6218        // Fourth...  does the caller itself have permission to access
6219        // this uri?
6220        if (!checkHoldingPermissionsLocked(pm, pi, callingUid, modeFlags)) {
6221            if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6222                throw new SecurityException("Uid " + callingUid
6223                        + " does not have permission to uri " + uri);
6224            }
6225        }
6226
6227        // Okay!  So here we are: the caller has the assumed permission
6228        // to the uri, and the target doesn't.  Let's now give this to
6229        // the target.
6230
6231        HashMap<Uri, UriPermission> targetUris
6232                = mGrantedUriPermissions.get(targetUid);
6233        if (targetUris == null) {
6234            targetUris = new HashMap<Uri, UriPermission>();
6235            mGrantedUriPermissions.put(targetUid, targetUris);
6236        }
6237
6238        UriPermission perm = targetUris.get(uri);
6239        if (perm == null) {
6240            perm = new UriPermission(targetUid, uri);
6241            targetUris.put(uri, perm);
6242
6243        }
6244        perm.modeFlags |= modeFlags;
6245        if (activity == null) {
6246            perm.globalModeFlags |= modeFlags;
6247        } else if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6248            perm.readActivities.add(activity);
6249            if (activity.readUriPermissions == null) {
6250                activity.readUriPermissions = new HashSet<UriPermission>();
6251            }
6252            activity.readUriPermissions.add(perm);
6253        } else if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6254            perm.writeActivities.add(activity);
6255            if (activity.writeUriPermissions == null) {
6256                activity.writeUriPermissions = new HashSet<UriPermission>();
6257            }
6258            activity.writeUriPermissions.add(perm);
6259        }
6260    }
6261
6262    private void grantUriPermissionFromIntentLocked(int callingUid,
6263            String targetPkg, Intent intent, HistoryRecord activity) {
6264        if (intent == null) {
6265            return;
6266        }
6267        Uri data = intent.getData();
6268        if (data == null) {
6269            return;
6270        }
6271        grantUriPermissionLocked(callingUid, targetPkg, data,
6272                intent.getFlags(), activity);
6273    }
6274
6275    public void grantUriPermission(IApplicationThread caller, String targetPkg,
6276            Uri uri, int modeFlags) {
6277        synchronized(this) {
6278            final ProcessRecord r = getRecordForAppLocked(caller);
6279            if (r == null) {
6280                throw new SecurityException("Unable to find app for caller "
6281                        + caller
6282                        + " when granting permission to uri " + uri);
6283            }
6284            if (targetPkg == null) {
6285                Log.w(TAG, "grantUriPermission: null target");
6286                return;
6287            }
6288            if (uri == null) {
6289                Log.w(TAG, "grantUriPermission: null uri");
6290                return;
6291            }
6292
6293            grantUriPermissionLocked(r.info.uid, targetPkg, uri, modeFlags,
6294                    null);
6295        }
6296    }
6297
6298    private void removeUriPermissionIfNeededLocked(UriPermission perm) {
6299        if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
6300                |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
6301            HashMap<Uri, UriPermission> perms
6302                    = mGrantedUriPermissions.get(perm.uid);
6303            if (perms != null) {
6304                perms.remove(perm.uri);
6305                if (perms.size() == 0) {
6306                    mGrantedUriPermissions.remove(perm.uid);
6307                }
6308            }
6309        }
6310    }
6311
6312    private void removeActivityUriPermissionsLocked(HistoryRecord activity) {
6313        if (activity.readUriPermissions != null) {
6314            for (UriPermission perm : activity.readUriPermissions) {
6315                perm.readActivities.remove(activity);
6316                if (perm.readActivities.size() == 0 && (perm.globalModeFlags
6317                        &Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0) {
6318                    perm.modeFlags &= ~Intent.FLAG_GRANT_READ_URI_PERMISSION;
6319                    removeUriPermissionIfNeededLocked(perm);
6320                }
6321            }
6322        }
6323        if (activity.writeUriPermissions != null) {
6324            for (UriPermission perm : activity.writeUriPermissions) {
6325                perm.writeActivities.remove(activity);
6326                if (perm.writeActivities.size() == 0 && (perm.globalModeFlags
6327                        &Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0) {
6328                    perm.modeFlags &= ~Intent.FLAG_GRANT_WRITE_URI_PERMISSION;
6329                    removeUriPermissionIfNeededLocked(perm);
6330                }
6331            }
6332        }
6333    }
6334
6335    private void revokeUriPermissionLocked(int callingUid, Uri uri,
6336            int modeFlags) {
6337        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
6338                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6339        if (modeFlags == 0) {
6340            return;
6341        }
6342
6343        final IPackageManager pm = ActivityThread.getPackageManager();
6344
6345        final String authority = uri.getAuthority();
6346        ProviderInfo pi = null;
6347        ContentProviderRecord cpr
6348                = (ContentProviderRecord)mProvidersByName.get(authority);
6349        if (cpr != null) {
6350            pi = cpr.info;
6351        } else {
6352            try {
6353                pi = pm.resolveContentProvider(authority,
6354                        PackageManager.GET_URI_PERMISSION_PATTERNS);
6355            } catch (RemoteException ex) {
6356            }
6357        }
6358        if (pi == null) {
6359            Log.w(TAG, "No content provider found for: " + authority);
6360            return;
6361        }
6362
6363        // Does the caller have this permission on the URI?
6364        if (!checkHoldingPermissionsLocked(pm, pi, callingUid, modeFlags)) {
6365            // Right now, if you are not the original owner of the permission,
6366            // you are not allowed to revoke it.
6367            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6368                throw new SecurityException("Uid " + callingUid
6369                        + " does not have permission to uri " + uri);
6370            //}
6371        }
6372
6373        // Go through all of the permissions and remove any that match.
6374        final List<String> SEGMENTS = uri.getPathSegments();
6375        if (SEGMENTS != null) {
6376            final int NS = SEGMENTS.size();
6377            int N = mGrantedUriPermissions.size();
6378            for (int i=0; i<N; i++) {
6379                HashMap<Uri, UriPermission> perms
6380                        = mGrantedUriPermissions.valueAt(i);
6381                Iterator<UriPermission> it = perms.values().iterator();
6382            toploop:
6383                while (it.hasNext()) {
6384                    UriPermission perm = it.next();
6385                    Uri targetUri = perm.uri;
6386                    if (!authority.equals(targetUri.getAuthority())) {
6387                        continue;
6388                    }
6389                    List<String> targetSegments = targetUri.getPathSegments();
6390                    if (targetSegments == null) {
6391                        continue;
6392                    }
6393                    if (targetSegments.size() < NS) {
6394                        continue;
6395                    }
6396                    for (int j=0; j<NS; j++) {
6397                        if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
6398                            continue toploop;
6399                        }
6400                    }
6401                    perm.clearModes(modeFlags);
6402                    if (perm.modeFlags == 0) {
6403                        it.remove();
6404                    }
6405                }
6406                if (perms.size() == 0) {
6407                    mGrantedUriPermissions.remove(
6408                            mGrantedUriPermissions.keyAt(i));
6409                    N--;
6410                    i--;
6411                }
6412            }
6413        }
6414    }
6415
6416    public void revokeUriPermission(IApplicationThread caller, Uri uri,
6417            int modeFlags) {
6418        synchronized(this) {
6419            final ProcessRecord r = getRecordForAppLocked(caller);
6420            if (r == null) {
6421                throw new SecurityException("Unable to find app for caller "
6422                        + caller
6423                        + " when revoking permission to uri " + uri);
6424            }
6425            if (uri == null) {
6426                Log.w(TAG, "revokeUriPermission: null uri");
6427                return;
6428            }
6429
6430            modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
6431                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6432            if (modeFlags == 0) {
6433                return;
6434            }
6435
6436            final IPackageManager pm = ActivityThread.getPackageManager();
6437
6438            final String authority = uri.getAuthority();
6439            ProviderInfo pi = null;
6440            ContentProviderRecord cpr
6441                    = (ContentProviderRecord)mProvidersByName.get(authority);
6442            if (cpr != null) {
6443                pi = cpr.info;
6444            } else {
6445                try {
6446                    pi = pm.resolveContentProvider(authority,
6447                            PackageManager.GET_URI_PERMISSION_PATTERNS);
6448                } catch (RemoteException ex) {
6449                }
6450            }
6451            if (pi == null) {
6452                Log.w(TAG, "No content provider found for: " + authority);
6453                return;
6454            }
6455
6456            revokeUriPermissionLocked(r.info.uid, uri, modeFlags);
6457        }
6458    }
6459
6460    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
6461        synchronized (this) {
6462            ProcessRecord app =
6463                who != null ? getRecordForAppLocked(who) : null;
6464            if (app == null) return;
6465
6466            Message msg = Message.obtain();
6467            msg.what = WAIT_FOR_DEBUGGER_MSG;
6468            msg.obj = app;
6469            msg.arg1 = waiting ? 1 : 0;
6470            mHandler.sendMessage(msg);
6471        }
6472    }
6473
6474    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
6475        outInfo.availMem = Process.getFreeMemory();
6476        outInfo.threshold = HOME_APP_MEM;
6477        outInfo.lowMemory = outInfo.availMem <
6478                (HOME_APP_MEM + ((HIDDEN_APP_MEM-HOME_APP_MEM)/2));
6479    }
6480
6481    // =========================================================
6482    // TASK MANAGEMENT
6483    // =========================================================
6484
6485    public List getTasks(int maxNum, int flags,
6486                         IThumbnailReceiver receiver) {
6487        ArrayList list = new ArrayList();
6488
6489        PendingThumbnailsRecord pending = null;
6490        IApplicationThread topThumbnail = null;
6491        HistoryRecord topRecord = null;
6492
6493        synchronized(this) {
6494            if (localLOGV) Log.v(
6495                TAG, "getTasks: max=" + maxNum + ", flags=" + flags
6496                + ", receiver=" + receiver);
6497
6498            if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
6499                    != PackageManager.PERMISSION_GRANTED) {
6500                if (receiver != null) {
6501                    // If the caller wants to wait for pending thumbnails,
6502                    // it ain't gonna get them.
6503                    try {
6504                        receiver.finished();
6505                    } catch (RemoteException ex) {
6506                    }
6507                }
6508                String msg = "Permission Denial: getTasks() from pid="
6509                        + Binder.getCallingPid()
6510                        + ", uid=" + Binder.getCallingUid()
6511                        + " requires " + android.Manifest.permission.GET_TASKS;
6512                Log.w(TAG, msg);
6513                throw new SecurityException(msg);
6514            }
6515
6516            int pos = mHistory.size()-1;
6517            HistoryRecord next =
6518                pos >= 0 ? (HistoryRecord)mHistory.get(pos) : null;
6519            HistoryRecord top = null;
6520            CharSequence topDescription = null;
6521            TaskRecord curTask = null;
6522            int numActivities = 0;
6523            int numRunning = 0;
6524            while (pos >= 0 && maxNum > 0) {
6525                final HistoryRecord r = next;
6526                pos--;
6527                next = pos >= 0 ? (HistoryRecord)mHistory.get(pos) : null;
6528
6529                // Initialize state for next task if needed.
6530                if (top == null ||
6531                        (top.state == ActivityState.INITIALIZING
6532                            && top.task == r.task)) {
6533                    top = r;
6534                    topDescription = r.description;
6535                    curTask = r.task;
6536                    numActivities = numRunning = 0;
6537                }
6538
6539                // Add 'r' into the current task.
6540                numActivities++;
6541                if (r.app != null && r.app.thread != null) {
6542                    numRunning++;
6543                }
6544                if (topDescription == null) {
6545                    topDescription = r.description;
6546                }
6547
6548                if (localLOGV) Log.v(
6549                    TAG, r.intent.getComponent().flattenToShortString()
6550                    + ": task=" + r.task);
6551
6552                // If the next one is a different task, generate a new
6553                // TaskInfo entry for what we have.
6554                if (next == null || next.task != curTask) {
6555                    ActivityManager.RunningTaskInfo ci
6556                            = new ActivityManager.RunningTaskInfo();
6557                    ci.id = curTask.taskId;
6558                    ci.baseActivity = r.intent.getComponent();
6559                    ci.topActivity = top.intent.getComponent();
6560                    ci.thumbnail = top.thumbnail;
6561                    ci.description = topDescription;
6562                    ci.numActivities = numActivities;
6563                    ci.numRunning = numRunning;
6564                    //System.out.println(
6565                    //    "#" + maxNum + ": " + " descr=" + ci.description);
6566                    if (ci.thumbnail == null && receiver != null) {
6567                        if (localLOGV) Log.v(
6568                            TAG, "State=" + top.state + "Idle=" + top.idle
6569                            + " app=" + top.app
6570                            + " thr=" + (top.app != null ? top.app.thread : null));
6571                        if (top.state == ActivityState.RESUMED
6572                                || top.state == ActivityState.PAUSING) {
6573                            if (top.idle && top.app != null
6574                                && top.app.thread != null) {
6575                                topRecord = top;
6576                                topThumbnail = top.app.thread;
6577                            } else {
6578                                top.thumbnailNeeded = true;
6579                            }
6580                        }
6581                        if (pending == null) {
6582                            pending = new PendingThumbnailsRecord(receiver);
6583                        }
6584                        pending.pendingRecords.add(top);
6585                    }
6586                    list.add(ci);
6587                    maxNum--;
6588                    top = null;
6589                }
6590            }
6591
6592            if (pending != null) {
6593                mPendingThumbnails.add(pending);
6594            }
6595        }
6596
6597        if (localLOGV) Log.v(TAG, "We have pending thumbnails: " + pending);
6598
6599        if (topThumbnail != null) {
6600            if (localLOGV) Log.v(TAG, "Requesting top thumbnail");
6601            try {
6602                topThumbnail.requestThumbnail(topRecord);
6603            } catch (Exception e) {
6604                Log.w(TAG, "Exception thrown when requesting thumbnail", e);
6605                sendPendingThumbnail(null, topRecord, null, null, true);
6606            }
6607        }
6608
6609        if (pending == null && receiver != null) {
6610            // In this case all thumbnails were available and the client
6611            // is being asked to be told when the remaining ones come in...
6612            // which is unusually, since the top-most currently running
6613            // activity should never have a canned thumbnail!  Oh well.
6614            try {
6615                receiver.finished();
6616            } catch (RemoteException ex) {
6617            }
6618        }
6619
6620        return list;
6621    }
6622
6623    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
6624            int flags) {
6625        synchronized (this) {
6626            enforceCallingPermission(android.Manifest.permission.GET_TASKS,
6627                    "getRecentTasks()");
6628
6629            final int N = mRecentTasks.size();
6630            ArrayList<ActivityManager.RecentTaskInfo> res
6631                    = new ArrayList<ActivityManager.RecentTaskInfo>(
6632                            maxNum < N ? maxNum : N);
6633            for (int i=0; i<N && maxNum > 0; i++) {
6634                TaskRecord tr = mRecentTasks.get(i);
6635                if (((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
6636                        || (tr.intent == null)
6637                        || ((tr.intent.getFlags()
6638                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
6639                    ActivityManager.RecentTaskInfo rti
6640                            = new ActivityManager.RecentTaskInfo();
6641                    rti.id = tr.numActivities > 0 ? tr.taskId : -1;
6642                    rti.baseIntent = new Intent(
6643                            tr.intent != null ? tr.intent : tr.affinityIntent);
6644                    rti.origActivity = tr.origActivity;
6645                    res.add(rti);
6646                    maxNum--;
6647                }
6648            }
6649            return res;
6650        }
6651    }
6652
6653    private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
6654        int j;
6655        TaskRecord startTask = ((HistoryRecord)mHistory.get(startIndex)).task;
6656        TaskRecord jt = startTask;
6657
6658        // First look backwards
6659        for (j=startIndex-1; j>=0; j--) {
6660            HistoryRecord r = (HistoryRecord)mHistory.get(j);
6661            if (r.task != jt) {
6662                jt = r.task;
6663                if (affinity.equals(jt.affinity)) {
6664                    return j;
6665                }
6666            }
6667        }
6668
6669        // Now look forwards
6670        final int N = mHistory.size();
6671        jt = startTask;
6672        for (j=startIndex+1; j<N; j++) {
6673            HistoryRecord r = (HistoryRecord)mHistory.get(j);
6674            if (r.task != jt) {
6675                if (affinity.equals(jt.affinity)) {
6676                    return j;
6677                }
6678                jt = r.task;
6679            }
6680        }
6681
6682        // Might it be at the top?
6683        if (affinity.equals(((HistoryRecord)mHistory.get(N-1)).task.affinity)) {
6684            return N-1;
6685        }
6686
6687        return -1;
6688    }
6689
6690    /**
6691     * Perform a reset of the given task, if needed as part of launching it.
6692     * Returns the new HistoryRecord at the top of the task.
6693     */
6694    private final HistoryRecord resetTaskIfNeededLocked(HistoryRecord taskTop,
6695            HistoryRecord newActivity) {
6696        boolean forceReset = (newActivity.info.flags
6697                &ActivityInfo.FLAG_CLEAR_TASK_ON_LAUNCH) != 0;
6698        if (taskTop.task.getInactiveDuration() > ACTIVITY_INACTIVE_RESET_TIME) {
6699            if ((newActivity.info.flags
6700                    &ActivityInfo.FLAG_ALWAYS_RETAIN_TASK_STATE) == 0) {
6701                forceReset = true;
6702            }
6703        }
6704
6705        final TaskRecord task = taskTop.task;
6706
6707        // We are going to move through the history list so that we can look
6708        // at each activity 'target' with 'below' either the interesting
6709        // activity immediately below it in the stack or null.
6710        HistoryRecord target = null;
6711        int targetI = 0;
6712        int taskTopI = -1;
6713        int replyChainEnd = -1;
6714        int lastReparentPos = -1;
6715        for (int i=mHistory.size()-1; i>=-1; i--) {
6716            HistoryRecord below = i >= 0 ? (HistoryRecord)mHistory.get(i) : null;
6717
6718            if (below != null && below.finishing) {
6719                continue;
6720            }
6721            if (target == null) {
6722                target = below;
6723                targetI = i;
6724                // If we were in the middle of a reply chain before this
6725                // task, it doesn't appear like the root of the chain wants
6726                // anything interesting, so drop it.
6727                replyChainEnd = -1;
6728                continue;
6729            }
6730
6731            final int flags = target.info.flags;
6732
6733            final boolean finishOnTaskLaunch =
6734                (flags&ActivityInfo.FLAG_FINISH_ON_TASK_LAUNCH) != 0;
6735            final boolean allowTaskReparenting =
6736                (flags&ActivityInfo.FLAG_ALLOW_TASK_REPARENTING) != 0;
6737
6738            if (target.task == task) {
6739                // We are inside of the task being reset...  we'll either
6740                // finish this activity, push it out for another task,
6741                // or leave it as-is.  We only do this
6742                // for activities that are not the root of the task (since
6743                // if we finish the root, we may no longer have the task!).
6744                if (taskTopI < 0) {
6745                    taskTopI = targetI;
6746                }
6747                if (below != null && below.task == task) {
6748                    final boolean clearWhenTaskReset =
6749                            (target.intent.getFlags()
6750                                    &Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0;
6751                    if (!finishOnTaskLaunch && !clearWhenTaskReset && target.resultTo != null) {
6752                        // If this activity is sending a reply to a previous
6753                        // activity, we can't do anything with it now until
6754                        // we reach the start of the reply chain.
6755                        // XXX note that we are assuming the result is always
6756                        // to the previous activity, which is almost always
6757                        // the case but we really shouldn't count on.
6758                        if (replyChainEnd < 0) {
6759                            replyChainEnd = targetI;
6760                        }
6761                    } else if (!finishOnTaskLaunch && !clearWhenTaskReset && allowTaskReparenting
6762                            && target.taskAffinity != null
6763                            && !target.taskAffinity.equals(task.affinity)) {
6764                        // If this activity has an affinity for another
6765                        // task, then we need to move it out of here.  We will
6766                        // move it as far out of the way as possible, to the
6767                        // bottom of the activity stack.  This also keeps it
6768                        // correctly ordered with any activities we previously
6769                        // moved.
6770                        HistoryRecord p = (HistoryRecord)mHistory.get(0);
6771                        if (target.taskAffinity != null
6772                                && target.taskAffinity.equals(p.task.affinity)) {
6773                            // If the activity currently at the bottom has the
6774                            // same task affinity as the one we are moving,
6775                            // then merge it into the same task.
6776                            target.task = p.task;
6777                            if (DEBUG_TASKS) Log.v(TAG, "Start pushing activity " + target
6778                                    + " out to bottom task " + p.task);
6779                        } else {
6780                            mCurTask++;
6781                            if (mCurTask <= 0) {
6782                                mCurTask = 1;
6783                            }
6784                            target.task = new TaskRecord(mCurTask, target.info, null,
6785                                    (target.info.flags&ActivityInfo.FLAG_CLEAR_TASK_ON_LAUNCH) != 0);
6786                            target.task.affinityIntent = target.intent;
6787                            if (DEBUG_TASKS) Log.v(TAG, "Start pushing activity " + target
6788                                    + " out to new task " + target.task);
6789                        }
6790                        mWindowManager.setAppGroupId(target, task.taskId);
6791                        if (replyChainEnd < 0) {
6792                            replyChainEnd = targetI;
6793                        }
6794                        int dstPos = 0;
6795                        for (int srcPos=targetI; srcPos<=replyChainEnd; srcPos++) {
6796                            p = (HistoryRecord)mHistory.get(srcPos);
6797                            if (p.finishing) {
6798                                continue;
6799                            }
6800                            if (DEBUG_TASKS) Log.v(TAG, "Pushing next activity " + p
6801                                    + " out to target's task " + target.task);
6802                            task.numActivities--;
6803                            p.task = target.task;
6804                            target.task.numActivities++;
6805                            mHistory.remove(srcPos);
6806                            mHistory.add(dstPos, p);
6807                            mWindowManager.moveAppToken(dstPos, p);
6808                            mWindowManager.setAppGroupId(p, p.task.taskId);
6809                            dstPos++;
6810                            if (VALIDATE_TOKENS) {
6811                                mWindowManager.validateAppTokens(mHistory);
6812                            }
6813                            i++;
6814                        }
6815                        if (taskTop == p) {
6816                            taskTop = below;
6817                        }
6818                        if (taskTopI == replyChainEnd) {
6819                            taskTopI = -1;
6820                        }
6821                        replyChainEnd = -1;
6822                        addRecentTask(target.task);
6823                    } else if (forceReset || finishOnTaskLaunch
6824                            || clearWhenTaskReset) {
6825                        // If the activity should just be removed -- either
6826                        // because it asks for it, or the task should be
6827                        // cleared -- then finish it and anything that is
6828                        // part of its reply chain.
6829                        if (clearWhenTaskReset) {
6830                            // In this case, we want to finish this activity
6831                            // and everything above it, so be sneaky and pretend
6832                            // like these are all in the reply chain.
6833                            replyChainEnd = targetI+1;
6834                            while (replyChainEnd < mHistory.size() &&
6835                                    ((HistoryRecord)mHistory.get(
6836                                                replyChainEnd)).task == task) {
6837                                replyChainEnd++;
6838                            }
6839                            replyChainEnd--;
6840                        } else if (replyChainEnd < 0) {
6841                            replyChainEnd = targetI;
6842                        }
6843                        HistoryRecord p = null;
6844                        for (int srcPos=targetI; srcPos<=replyChainEnd; srcPos++) {
6845                            p = (HistoryRecord)mHistory.get(srcPos);
6846                            if (p.finishing) {
6847                                continue;
6848                            }
6849                            if (finishActivityLocked(p, srcPos,
6850                                    Activity.RESULT_CANCELED, null, "reset")) {
6851                                replyChainEnd--;
6852                                srcPos--;
6853                            }
6854                        }
6855                        if (taskTop == p) {
6856                            taskTop = below;
6857                        }
6858                        if (taskTopI == replyChainEnd) {
6859                            taskTopI = -1;
6860                        }
6861                        replyChainEnd = -1;
6862                    } else {
6863                        // If we were in the middle of a chain, well the
6864                        // activity that started it all doesn't want anything
6865                        // special, so leave it all as-is.
6866                        replyChainEnd = -1;
6867                    }
6868                } else {
6869                    // Reached the bottom of the task -- any reply chain
6870                    // should be left as-is.
6871                    replyChainEnd = -1;
6872                }
6873
6874            } else if (target.resultTo != null) {
6875                // If this activity is sending a reply to a previous
6876                // activity, we can't do anything with it now until
6877                // we reach the start of the reply chain.
6878                // XXX note that we are assuming the result is always
6879                // to the previous activity, which is almost always
6880                // the case but we really shouldn't count on.
6881                if (replyChainEnd < 0) {
6882                    replyChainEnd = targetI;
6883                }
6884
6885            } else if (taskTopI >= 0 && allowTaskReparenting
6886                    && task.affinity != null
6887                    && task.affinity.equals(target.taskAffinity)) {
6888                // We are inside of another task...  if this activity has
6889                // an affinity for our task, then either remove it if we are
6890                // clearing or move it over to our task.  Note that
6891                // we currently punt on the case where we are resetting a
6892                // task that is not at the top but who has activities above
6893                // with an affinity to it...  this is really not a normal
6894                // case, and we will need to later pull that task to the front
6895                // and usually at that point we will do the reset and pick
6896                // up those remaining activities.  (This only happens if
6897                // someone starts an activity in a new task from an activity
6898                // in a task that is not currently on top.)
6899                if (forceReset || finishOnTaskLaunch) {
6900                    if (replyChainEnd < 0) {
6901                        replyChainEnd = targetI;
6902                    }
6903                    HistoryRecord p = null;
6904                    for (int srcPos=targetI; srcPos<=replyChainEnd; srcPos++) {
6905                        p = (HistoryRecord)mHistory.get(srcPos);
6906                        if (p.finishing) {
6907                            continue;
6908                        }
6909                        if (finishActivityLocked(p, srcPos,
6910                                Activity.RESULT_CANCELED, null, "reset")) {
6911                            taskTopI--;
6912                            lastReparentPos--;
6913                            replyChainEnd--;
6914                            srcPos--;
6915                        }
6916                    }
6917                    replyChainEnd = -1;
6918                } else {
6919                    if (replyChainEnd < 0) {
6920                        replyChainEnd = targetI;
6921                    }
6922                    for (int srcPos=replyChainEnd; srcPos>=targetI; srcPos--) {
6923                        HistoryRecord p = (HistoryRecord)mHistory.get(srcPos);
6924                        if (p.finishing) {
6925                            continue;
6926                        }
6927                        if (lastReparentPos < 0) {
6928                            lastReparentPos = taskTopI;
6929                            taskTop = p;
6930                        } else {
6931                            lastReparentPos--;
6932                        }
6933                        mHistory.remove(srcPos);
6934                        p.task.numActivities--;
6935                        p.task = task;
6936                        mHistory.add(lastReparentPos, p);
6937                        if (DEBUG_TASKS) Log.v(TAG, "Pulling activity " + p
6938                                + " in to resetting task " + task);
6939                        task.numActivities++;
6940                        mWindowManager.moveAppToken(lastReparentPos, p);
6941                        mWindowManager.setAppGroupId(p, p.task.taskId);
6942                        if (VALIDATE_TOKENS) {
6943                            mWindowManager.validateAppTokens(mHistory);
6944                        }
6945                    }
6946                    replyChainEnd = -1;
6947
6948                    // Now we've moved it in to place...  but what if this is
6949                    // a singleTop activity and we have put it on top of another
6950                    // instance of the same activity?  Then we drop the instance
6951                    // below so it remains singleTop.
6952                    if (target.info.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP) {
6953                        for (int j=lastReparentPos-1; j>=0; j--) {
6954                            HistoryRecord p = (HistoryRecord)mHistory.get(j);
6955                            if (p.finishing) {
6956                                continue;
6957                            }
6958                            if (p.intent.getComponent().equals(target.intent.getComponent())) {
6959                                if (finishActivityLocked(p, j,
6960                                        Activity.RESULT_CANCELED, null, "replace")) {
6961                                    taskTopI--;
6962                                    lastReparentPos--;
6963                                }
6964                            }
6965                        }
6966                    }
6967                }
6968            }
6969
6970            target = below;
6971            targetI = i;
6972        }
6973
6974        return taskTop;
6975    }
6976
6977    /**
6978     * TODO: Add mController hook
6979     */
6980    public void moveTaskToFront(int task) {
6981        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
6982                "moveTaskToFront()");
6983
6984        synchronized(this) {
6985            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
6986                    Binder.getCallingUid(), "Task to front")) {
6987                return;
6988            }
6989            final long origId = Binder.clearCallingIdentity();
6990            try {
6991                int N = mRecentTasks.size();
6992                for (int i=0; i<N; i++) {
6993                    TaskRecord tr = mRecentTasks.get(i);
6994                    if (tr.taskId == task) {
6995                        moveTaskToFrontLocked(tr, null);
6996                        return;
6997                    }
6998                }
6999                for (int i=mHistory.size()-1; i>=0; i--) {
7000                    HistoryRecord hr = (HistoryRecord)mHistory.get(i);
7001                    if (hr.task.taskId == task) {
7002                        moveTaskToFrontLocked(hr.task, null);
7003                        return;
7004                    }
7005                }
7006            } finally {
7007                Binder.restoreCallingIdentity(origId);
7008            }
7009        }
7010    }
7011
7012    private final void moveTaskToFrontLocked(TaskRecord tr, HistoryRecord reason) {
7013        if (DEBUG_SWITCH) Log.v(TAG, "moveTaskToFront: " + tr);
7014
7015        final int task = tr.taskId;
7016        int top = mHistory.size()-1;
7017
7018        if (top < 0 || ((HistoryRecord)mHistory.get(top)).task.taskId == task) {
7019            // nothing to do!
7020            return;
7021        }
7022
7023        ArrayList moved = new ArrayList();
7024
7025        // Applying the affinities may have removed entries from the history,
7026        // so get the size again.
7027        top = mHistory.size()-1;
7028        int pos = top;
7029
7030        // Shift all activities with this task up to the top
7031        // of the stack, keeping them in the same internal order.
7032        while (pos >= 0) {
7033            HistoryRecord r = (HistoryRecord)mHistory.get(pos);
7034            if (localLOGV) Log.v(
7035                TAG, "At " + pos + " ckp " + r.task + ": " + r);
7036            boolean first = true;
7037            if (r.task.taskId == task) {
7038                if (localLOGV) Log.v(TAG, "Removing and adding at " + top);
7039                mHistory.remove(pos);
7040                mHistory.add(top, r);
7041                moved.add(0, r);
7042                top--;
7043                if (first) {
7044                    addRecentTask(r.task);
7045                    first = false;
7046                }
7047            }
7048            pos--;
7049        }
7050
7051        if (DEBUG_TRANSITION) Log.v(TAG,
7052                "Prepare to front transition: task=" + tr);
7053        if (reason != null &&
7054                (reason.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) {
7055            mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_NONE);
7056            HistoryRecord r = topRunningActivityLocked(null);
7057            if (r != null) {
7058                mNoAnimActivities.add(r);
7059            }
7060        } else {
7061            mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_TASK_TO_FRONT);
7062        }
7063
7064        mWindowManager.moveAppTokensToTop(moved);
7065        if (VALIDATE_TOKENS) {
7066            mWindowManager.validateAppTokens(mHistory);
7067        }
7068
7069        finishTaskMove(task);
7070        EventLog.writeEvent(LOG_TASK_TO_FRONT, task);
7071    }
7072
7073    private final void finishTaskMove(int task) {
7074        resumeTopActivityLocked(null);
7075    }
7076
7077    public void moveTaskToBack(int task) {
7078        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7079                "moveTaskToBack()");
7080
7081        synchronized(this) {
7082            if (mResumedActivity != null && mResumedActivity.task.taskId == task) {
7083                if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7084                        Binder.getCallingUid(), "Task to back")) {
7085                    return;
7086                }
7087            }
7088            final long origId = Binder.clearCallingIdentity();
7089            moveTaskToBackLocked(task, null);
7090            Binder.restoreCallingIdentity(origId);
7091        }
7092    }
7093
7094    /**
7095     * Moves an activity, and all of the other activities within the same task, to the bottom
7096     * of the history stack.  The activity's order within the task is unchanged.
7097     *
7098     * @param token A reference to the activity we wish to move
7099     * @param nonRoot If false then this only works if the activity is the root
7100     *                of a task; if true it will work for any activity in a task.
7101     * @return Returns true if the move completed, false if not.
7102     */
7103    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7104        synchronized(this) {
7105            final long origId = Binder.clearCallingIdentity();
7106            int taskId = getTaskForActivityLocked(token, !nonRoot);
7107            if (taskId >= 0) {
7108                return moveTaskToBackLocked(taskId, null);
7109            }
7110            Binder.restoreCallingIdentity(origId);
7111        }
7112        return false;
7113    }
7114
7115    /**
7116     * Worker method for rearranging history stack.  Implements the function of moving all
7117     * activities for a specific task (gathering them if disjoint) into a single group at the
7118     * bottom of the stack.
7119     *
7120     * If a watcher is installed, the action is preflighted and the watcher has an opportunity
7121     * to premeptively cancel the move.
7122     *
7123     * @param task The taskId to collect and move to the bottom.
7124     * @return Returns true if the move completed, false if not.
7125     */
7126    private final boolean moveTaskToBackLocked(int task, HistoryRecord reason) {
7127        Log.i(TAG, "moveTaskToBack: " + task);
7128
7129        // If we have a watcher, preflight the move before committing to it.  First check
7130        // for *other* available tasks, but if none are available, then try again allowing the
7131        // current task to be selected.
7132        if (mController != null) {
7133            HistoryRecord next = topRunningActivityLocked(null, task);
7134            if (next == null) {
7135                next = topRunningActivityLocked(null, 0);
7136            }
7137            if (next != null) {
7138                // ask watcher if this is allowed
7139                boolean moveOK = true;
7140                try {
7141                    moveOK = mController.activityResuming(next.packageName);
7142                } catch (RemoteException e) {
7143                    mController = null;
7144                }
7145                if (!moveOK) {
7146                    return false;
7147                }
7148            }
7149        }
7150
7151        ArrayList moved = new ArrayList();
7152
7153        if (DEBUG_TRANSITION) Log.v(TAG,
7154                "Prepare to back transition: task=" + task);
7155        mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_TASK_TO_BACK);
7156
7157        final int N = mHistory.size();
7158        int bottom = 0;
7159        int pos = 0;
7160
7161        // Shift all activities with this task down to the bottom
7162        // of the stack, keeping them in the same internal order.
7163        while (pos < N) {
7164            HistoryRecord r = (HistoryRecord)mHistory.get(pos);
7165            if (localLOGV) Log.v(
7166                TAG, "At " + pos + " ckp " + r.task + ": " + r);
7167            if (r.task.taskId == task) {
7168                if (localLOGV) Log.v(TAG, "Removing and adding at " + (N-1));
7169                mHistory.remove(pos);
7170                mHistory.add(bottom, r);
7171                moved.add(r);
7172                bottom++;
7173            }
7174            pos++;
7175        }
7176
7177        if (reason != null &&
7178                (reason.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) {
7179            mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_NONE);
7180            HistoryRecord r = topRunningActivityLocked(null);
7181            if (r != null) {
7182                mNoAnimActivities.add(r);
7183            }
7184        } else {
7185            mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_TASK_TO_FRONT);
7186        }
7187        mWindowManager.moveAppTokensToBottom(moved);
7188        if (VALIDATE_TOKENS) {
7189            mWindowManager.validateAppTokens(mHistory);
7190        }
7191
7192        finishTaskMove(task);
7193        return true;
7194    }
7195
7196    public void moveTaskBackwards(int task) {
7197        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7198                "moveTaskBackwards()");
7199
7200        synchronized(this) {
7201            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7202                    Binder.getCallingUid(), "Task backwards")) {
7203                return;
7204            }
7205            final long origId = Binder.clearCallingIdentity();
7206            moveTaskBackwardsLocked(task);
7207            Binder.restoreCallingIdentity(origId);
7208        }
7209    }
7210
7211    private final void moveTaskBackwardsLocked(int task) {
7212        Log.e(TAG, "moveTaskBackwards not yet implemented!");
7213    }
7214
7215    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7216        synchronized(this) {
7217            return getTaskForActivityLocked(token, onlyRoot);
7218        }
7219    }
7220
7221    int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
7222        final int N = mHistory.size();
7223        TaskRecord lastTask = null;
7224        for (int i=0; i<N; i++) {
7225            HistoryRecord r = (HistoryRecord)mHistory.get(i);
7226            if (r == token) {
7227                if (!onlyRoot || lastTask != r.task) {
7228                    return r.task.taskId;
7229                }
7230                return -1;
7231            }
7232            lastTask = r.task;
7233        }
7234
7235        return -1;
7236    }
7237
7238    /**
7239     * Returns the top activity in any existing task matching the given
7240     * Intent.  Returns null if no such task is found.
7241     */
7242    private HistoryRecord findTaskLocked(Intent intent, ActivityInfo info) {
7243        ComponentName cls = intent.getComponent();
7244        if (info.targetActivity != null) {
7245            cls = new ComponentName(info.packageName, info.targetActivity);
7246        }
7247
7248        TaskRecord cp = null;
7249
7250        final int N = mHistory.size();
7251        for (int i=(N-1); i>=0; i--) {
7252            HistoryRecord r = (HistoryRecord)mHistory.get(i);
7253            if (!r.finishing && r.task != cp
7254                    && r.launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
7255                cp = r.task;
7256                //Log.i(TAG, "Comparing existing cls=" + r.task.intent.getComponent().flattenToShortString()
7257                //        + "/aff=" + r.task.affinity + " to new cls="
7258                //        + intent.getComponent().flattenToShortString() + "/aff=" + taskAffinity);
7259                if (r.task.affinity != null) {
7260                    if (r.task.affinity.equals(info.taskAffinity)) {
7261                        //Log.i(TAG, "Found matching affinity!");
7262                        return r;
7263                    }
7264                } else if (r.task.intent != null
7265                        && r.task.intent.getComponent().equals(cls)) {
7266                    //Log.i(TAG, "Found matching class!");
7267                    //dump();
7268                    //Log.i(TAG, "For Intent " + intent + " bringing to top: " + r.intent);
7269                    return r;
7270                } else if (r.task.affinityIntent != null
7271                        && r.task.affinityIntent.getComponent().equals(cls)) {
7272                    //Log.i(TAG, "Found matching class!");
7273                    //dump();
7274                    //Log.i(TAG, "For Intent " + intent + " bringing to top: " + r.intent);
7275                    return r;
7276                }
7277            }
7278        }
7279
7280        return null;
7281    }
7282
7283    /**
7284     * Returns the first activity (starting from the top of the stack) that
7285     * is the same as the given activity.  Returns null if no such activity
7286     * is found.
7287     */
7288    private HistoryRecord findActivityLocked(Intent intent, ActivityInfo info) {
7289        ComponentName cls = intent.getComponent();
7290        if (info.targetActivity != null) {
7291            cls = new ComponentName(info.packageName, info.targetActivity);
7292        }
7293
7294        final int N = mHistory.size();
7295        for (int i=(N-1); i>=0; i--) {
7296            HistoryRecord r = (HistoryRecord)mHistory.get(i);
7297            if (!r.finishing) {
7298                if (r.intent.getComponent().equals(cls)) {
7299                    //Log.i(TAG, "Found matching class!");
7300                    //dump();
7301                    //Log.i(TAG, "For Intent " + intent + " bringing to top: " + r.intent);
7302                    return r;
7303                }
7304            }
7305        }
7306
7307        return null;
7308    }
7309
7310    public void finishOtherInstances(IBinder token, ComponentName className) {
7311        synchronized(this) {
7312            final long origId = Binder.clearCallingIdentity();
7313
7314            int N = mHistory.size();
7315            TaskRecord lastTask = null;
7316            for (int i=0; i<N; i++) {
7317                HistoryRecord r = (HistoryRecord)mHistory.get(i);
7318                if (r.realActivity.equals(className)
7319                        && r != token && lastTask != r.task) {
7320                    if (finishActivityLocked(r, i, Activity.RESULT_CANCELED,
7321                            null, "others")) {
7322                        i--;
7323                        N--;
7324                    }
7325                }
7326                lastTask = r.task;
7327            }
7328
7329            Binder.restoreCallingIdentity(origId);
7330        }
7331    }
7332
7333    // =========================================================
7334    // THUMBNAILS
7335    // =========================================================
7336
7337    public void reportThumbnail(IBinder token,
7338            Bitmap thumbnail, CharSequence description) {
7339        //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
7340        final long origId = Binder.clearCallingIdentity();
7341        sendPendingThumbnail(null, token, thumbnail, description, true);
7342        Binder.restoreCallingIdentity(origId);
7343    }
7344
7345    final void sendPendingThumbnail(HistoryRecord r, IBinder token,
7346            Bitmap thumbnail, CharSequence description, boolean always) {
7347        TaskRecord task = null;
7348        ArrayList receivers = null;
7349
7350        //System.out.println("Send pending thumbnail: " + r);
7351
7352        synchronized(this) {
7353            if (r == null) {
7354                int index = indexOfTokenLocked(token);
7355                if (index < 0) {
7356                    return;
7357                }
7358                r = (HistoryRecord)mHistory.get(index);
7359            }
7360            if (thumbnail == null) {
7361                thumbnail = r.thumbnail;
7362                description = r.description;
7363            }
7364            if (thumbnail == null && !always) {
7365                // If there is no thumbnail, and this entry is not actually
7366                // going away, then abort for now and pick up the next
7367                // thumbnail we get.
7368                return;
7369            }
7370            task = r.task;
7371
7372            int N = mPendingThumbnails.size();
7373            int i=0;
7374            while (i<N) {
7375                PendingThumbnailsRecord pr =
7376                    (PendingThumbnailsRecord)mPendingThumbnails.get(i);
7377                //System.out.println("Looking in " + pr.pendingRecords);
7378                if (pr.pendingRecords.remove(r)) {
7379                    if (receivers == null) {
7380                        receivers = new ArrayList();
7381                    }
7382                    receivers.add(pr);
7383                    if (pr.pendingRecords.size() == 0) {
7384                        pr.finished = true;
7385                        mPendingThumbnails.remove(i);
7386                        N--;
7387                        continue;
7388                    }
7389                }
7390                i++;
7391            }
7392        }
7393
7394        if (receivers != null) {
7395            final int N = receivers.size();
7396            for (int i=0; i<N; i++) {
7397                try {
7398                    PendingThumbnailsRecord pr =
7399                        (PendingThumbnailsRecord)receivers.get(i);
7400                    pr.receiver.newThumbnail(
7401                        task != null ? task.taskId : -1, thumbnail, description);
7402                    if (pr.finished) {
7403                        pr.receiver.finished();
7404                    }
7405                } catch (Exception e) {
7406                    Log.w(TAG, "Exception thrown when sending thumbnail", e);
7407                }
7408            }
7409        }
7410    }
7411
7412    // =========================================================
7413    // CONTENT PROVIDERS
7414    // =========================================================
7415
7416    private final List generateApplicationProvidersLocked(ProcessRecord app) {
7417        List providers = null;
7418        try {
7419            providers = ActivityThread.getPackageManager().
7420                queryContentProviders(app.processName, app.info.uid,
7421                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
7422        } catch (RemoteException ex) {
7423        }
7424        if (providers != null) {
7425            final int N = providers.size();
7426            for (int i=0; i<N; i++) {
7427                ProviderInfo cpi =
7428                    (ProviderInfo)providers.get(i);
7429                ContentProviderRecord cpr =
7430                    (ContentProviderRecord)mProvidersByClass.get(cpi.name);
7431                if (cpr == null) {
7432                    cpr = new ContentProviderRecord(cpi, app.info);
7433                    mProvidersByClass.put(cpi.name, cpr);
7434                }
7435                app.pubProviders.put(cpi.name, cpr);
7436                app.addPackage(cpi.applicationInfo.packageName);
7437                ensurePackageDexOpt(cpi.applicationInfo.packageName);
7438            }
7439        }
7440        return providers;
7441    }
7442
7443    private final String checkContentProviderPermissionLocked(
7444            ProviderInfo cpi, ProcessRecord r, int mode) {
7445        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
7446        final int callingUid = (r != null) ? r.info.uid : Binder.getCallingUid();
7447        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
7448                cpi.exported ? -1 : cpi.applicationInfo.uid)
7449                == PackageManager.PERMISSION_GRANTED
7450                && mode == ParcelFileDescriptor.MODE_READ_ONLY || mode == -1) {
7451            return null;
7452        }
7453        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
7454                cpi.exported ? -1 : cpi.applicationInfo.uid)
7455                == PackageManager.PERMISSION_GRANTED) {
7456            return null;
7457        }
7458
7459        PathPermission[] pps = cpi.pathPermissions;
7460        if (pps != null) {
7461            int i = pps.length;
7462            while (i > 0) {
7463                i--;
7464                PathPermission pp = pps[i];
7465                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
7466                        cpi.exported ? -1 : cpi.applicationInfo.uid)
7467                        == PackageManager.PERMISSION_GRANTED
7468                        && mode == ParcelFileDescriptor.MODE_READ_ONLY || mode == -1) {
7469                    return null;
7470                }
7471                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
7472                        cpi.exported ? -1 : cpi.applicationInfo.uid)
7473                        == PackageManager.PERMISSION_GRANTED) {
7474                    return null;
7475                }
7476            }
7477        }
7478
7479        String msg = "Permission Denial: opening provider " + cpi.name
7480                + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7481                + ", uid=" + callingUid + ") requires "
7482                + cpi.readPermission + " or " + cpi.writePermission;
7483        Log.w(TAG, msg);
7484        return msg;
7485    }
7486
7487    private final ContentProviderHolder getContentProviderImpl(
7488        IApplicationThread caller, String name) {
7489        ContentProviderRecord cpr;
7490        ProviderInfo cpi = null;
7491
7492        synchronized(this) {
7493            ProcessRecord r = null;
7494            if (caller != null) {
7495                r = getRecordForAppLocked(caller);
7496                if (r == null) {
7497                    throw new SecurityException(
7498                            "Unable to find app for caller " + caller
7499                          + " (pid=" + Binder.getCallingPid()
7500                          + ") when getting content provider " + name);
7501                }
7502            }
7503
7504            // First check if this content provider has been published...
7505            cpr = (ContentProviderRecord)mProvidersByName.get(name);
7506            if (cpr != null) {
7507                cpi = cpr.info;
7508                if (checkContentProviderPermissionLocked(cpi, r, -1) != null) {
7509                    return new ContentProviderHolder(cpi,
7510                            cpi.readPermission != null
7511                                    ? cpi.readPermission : cpi.writePermission);
7512                }
7513
7514                if (r != null && cpr.canRunHere(r)) {
7515                    // This provider has been published or is in the process
7516                    // of being published...  but it is also allowed to run
7517                    // in the caller's process, so don't make a connection
7518                    // and just let the caller instantiate its own instance.
7519                    if (cpr.provider != null) {
7520                        // don't give caller the provider object, it needs
7521                        // to make its own.
7522                        cpr = new ContentProviderRecord(cpr);
7523                    }
7524                    return cpr;
7525                }
7526
7527                final long origId = Binder.clearCallingIdentity();
7528
7529                // In this case the provider instance already exists, so we can
7530                // return it right away.
7531                if (r != null) {
7532                    if (DEBUG_PROVIDER) Log.v(TAG,
7533                            "Adding provider requested by "
7534                            + r.processName + " from process "
7535                            + cpr.info.processName);
7536                    r.conProviders.add(cpr);
7537                    cpr.clients.add(r);
7538                } else {
7539                    cpr.externals++;
7540                }
7541
7542                if (cpr.app != null) {
7543                    updateOomAdjLocked(cpr.app);
7544                }
7545
7546                Binder.restoreCallingIdentity(origId);
7547
7548            } else {
7549                try {
7550                    cpi = ActivityThread.getPackageManager().
7551                        resolveContentProvider(name,
7552                                STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
7553                } catch (RemoteException ex) {
7554                }
7555                if (cpi == null) {
7556                    return null;
7557                }
7558
7559                if (checkContentProviderPermissionLocked(cpi, r, -1) != null) {
7560                    return new ContentProviderHolder(cpi,
7561                            cpi.readPermission != null
7562                                    ? cpi.readPermission : cpi.writePermission);
7563                }
7564
7565                cpr = (ContentProviderRecord)mProvidersByClass.get(cpi.name);
7566                final boolean firstClass = cpr == null;
7567                if (firstClass) {
7568                    try {
7569                        ApplicationInfo ai =
7570                            ActivityThread.getPackageManager().
7571                                getApplicationInfo(
7572                                        cpi.applicationInfo.packageName,
7573                                        STOCK_PM_FLAGS);
7574                        if (ai == null) {
7575                            Log.w(TAG, "No package info for content provider "
7576                                    + cpi.name);
7577                            return null;
7578                        }
7579                        cpr = new ContentProviderRecord(cpi, ai);
7580                    } catch (RemoteException ex) {
7581                        // pm is in same process, this will never happen.
7582                    }
7583                }
7584
7585                if (r != null && cpr.canRunHere(r)) {
7586                    // If this is a multiprocess provider, then just return its
7587                    // info and allow the caller to instantiate it.  Only do
7588                    // this if the provider is the same user as the caller's
7589                    // process, or can run as root (so can be in any process).
7590                    return cpr;
7591                }
7592
7593                if (DEBUG_PROVIDER) {
7594                    RuntimeException e = new RuntimeException("here");
7595                    Log.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.info.uid
7596                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
7597                }
7598
7599                // This is single process, and our app is now connecting to it.
7600                // See if we are already in the process of launching this
7601                // provider.
7602                final int N = mLaunchingProviders.size();
7603                int i;
7604                for (i=0; i<N; i++) {
7605                    if (mLaunchingProviders.get(i) == cpr) {
7606                        break;
7607                    }
7608                }
7609
7610                // If the provider is not already being launched, then get it
7611                // started.
7612                if (i >= N) {
7613                    final long origId = Binder.clearCallingIdentity();
7614                    ProcessRecord proc = startProcessLocked(cpi.processName,
7615                            cpr.appInfo, false, 0, "content provider",
7616                            new ComponentName(cpi.applicationInfo.packageName,
7617                                    cpi.name), false);
7618                    if (proc == null) {
7619                        Log.w(TAG, "Unable to launch app "
7620                                + cpi.applicationInfo.packageName + "/"
7621                                + cpi.applicationInfo.uid + " for provider "
7622                                + name + ": process is bad");
7623                        return null;
7624                    }
7625                    cpr.launchingApp = proc;
7626                    mLaunchingProviders.add(cpr);
7627                    Binder.restoreCallingIdentity(origId);
7628                }
7629
7630                // Make sure the provider is published (the same provider class
7631                // may be published under multiple names).
7632                if (firstClass) {
7633                    mProvidersByClass.put(cpi.name, cpr);
7634                }
7635                mProvidersByName.put(name, cpr);
7636
7637                if (r != null) {
7638                    if (DEBUG_PROVIDER) Log.v(TAG,
7639                            "Adding provider requested by "
7640                            + r.processName + " from process "
7641                            + cpr.info.processName);
7642                    r.conProviders.add(cpr);
7643                    cpr.clients.add(r);
7644                } else {
7645                    cpr.externals++;
7646                }
7647            }
7648        }
7649
7650        // Wait for the provider to be published...
7651        synchronized (cpr) {
7652            while (cpr.provider == null) {
7653                if (cpr.launchingApp == null) {
7654                    Log.w(TAG, "Unable to launch app "
7655                            + cpi.applicationInfo.packageName + "/"
7656                            + cpi.applicationInfo.uid + " for provider "
7657                            + name + ": launching app became null");
7658                    EventLog.writeEvent(LOG_AM_PROVIDER_LOST_PROCESS,
7659                            cpi.applicationInfo.packageName,
7660                            cpi.applicationInfo.uid, name);
7661                    return null;
7662                }
7663                try {
7664                    cpr.wait();
7665                } catch (InterruptedException ex) {
7666                }
7667            }
7668        }
7669        return cpr;
7670    }
7671
7672    public final ContentProviderHolder getContentProvider(
7673            IApplicationThread caller, String name) {
7674        if (caller == null) {
7675            String msg = "null IApplicationThread when getting content provider "
7676                    + name;
7677            Log.w(TAG, msg);
7678            throw new SecurityException(msg);
7679        }
7680
7681        return getContentProviderImpl(caller, name);
7682    }
7683
7684    private ContentProviderHolder getContentProviderExternal(String name) {
7685        return getContentProviderImpl(null, name);
7686    }
7687
7688    /**
7689     * Drop a content provider from a ProcessRecord's bookkeeping
7690     * @param cpr
7691     */
7692    public void removeContentProvider(IApplicationThread caller, String name) {
7693        synchronized (this) {
7694            ContentProviderRecord cpr = (ContentProviderRecord)mProvidersByName.get(name);
7695            if(cpr == null) {
7696                // remove from mProvidersByClass
7697                if (DEBUG_PROVIDER) Log.v(TAG, name +
7698                        " provider not found in providers list");
7699                return;
7700            }
7701            final ProcessRecord r = getRecordForAppLocked(caller);
7702            if (r == null) {
7703                throw new SecurityException(
7704                        "Unable to find app for caller " + caller +
7705                        " when removing content provider " + name);
7706            }
7707            //update content provider record entry info
7708            ContentProviderRecord localCpr = (ContentProviderRecord)
7709                    mProvidersByClass.get(cpr.info.name);
7710            if (DEBUG_PROVIDER) Log.v(TAG, "Removing provider requested by "
7711                    + r.info.processName + " from process "
7712                    + localCpr.appInfo.processName);
7713            if (localCpr.app == r) {
7714                //should not happen. taken care of as a local provider
7715                Log.w(TAG, "removeContentProvider called on local provider: "
7716                        + cpr.info.name + " in process " + r.processName);
7717                return;
7718            } else {
7719                localCpr.clients.remove(r);
7720                r.conProviders.remove(localCpr);
7721            }
7722            updateOomAdjLocked();
7723        }
7724    }
7725
7726    private void removeContentProviderExternal(String name) {
7727        synchronized (this) {
7728            ContentProviderRecord cpr = (ContentProviderRecord)mProvidersByName.get(name);
7729            if(cpr == null) {
7730                //remove from mProvidersByClass
7731                if(localLOGV) Log.v(TAG, name+" content provider not found in providers list");
7732                return;
7733            }
7734
7735            //update content provider record entry info
7736            ContentProviderRecord localCpr = (ContentProviderRecord) mProvidersByClass.get(cpr.info.name);
7737            localCpr.externals--;
7738            if (localCpr.externals < 0) {
7739                Log.e(TAG, "Externals < 0 for content provider " + localCpr);
7740            }
7741            updateOomAdjLocked();
7742        }
7743    }
7744
7745    public final void publishContentProviders(IApplicationThread caller,
7746            List<ContentProviderHolder> providers) {
7747        if (providers == null) {
7748            return;
7749        }
7750
7751        synchronized(this) {
7752            final ProcessRecord r = getRecordForAppLocked(caller);
7753            if (r == null) {
7754                throw new SecurityException(
7755                        "Unable to find app for caller " + caller
7756                      + " (pid=" + Binder.getCallingPid()
7757                      + ") when publishing content providers");
7758            }
7759
7760            final long origId = Binder.clearCallingIdentity();
7761
7762            final int N = providers.size();
7763            for (int i=0; i<N; i++) {
7764                ContentProviderHolder src = providers.get(i);
7765                if (src == null || src.info == null || src.provider == null) {
7766                    continue;
7767                }
7768                ContentProviderRecord dst =
7769                    (ContentProviderRecord)r.pubProviders.get(src.info.name);
7770                if (dst != null) {
7771                    mProvidersByClass.put(dst.info.name, dst);
7772                    String names[] = dst.info.authority.split(";");
7773                    for (int j = 0; j < names.length; j++) {
7774                        mProvidersByName.put(names[j], dst);
7775                    }
7776
7777                    int NL = mLaunchingProviders.size();
7778                    int j;
7779                    for (j=0; j<NL; j++) {
7780                        if (mLaunchingProviders.get(j) == dst) {
7781                            mLaunchingProviders.remove(j);
7782                            j--;
7783                            NL--;
7784                        }
7785                    }
7786                    synchronized (dst) {
7787                        dst.provider = src.provider;
7788                        dst.app = r;
7789                        dst.notifyAll();
7790                    }
7791                    updateOomAdjLocked(r);
7792                }
7793            }
7794
7795            Binder.restoreCallingIdentity(origId);
7796        }
7797    }
7798
7799    public static final void installSystemProviders() {
7800        ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
7801        List providers = mSelf.generateApplicationProvidersLocked(app);
7802        mSystemThread.installSystemProviders(providers);
7803    }
7804
7805    // =========================================================
7806    // GLOBAL MANAGEMENT
7807    // =========================================================
7808
7809    final ProcessRecord newProcessRecordLocked(IApplicationThread thread,
7810            ApplicationInfo info, String customProcess) {
7811        String proc = customProcess != null ? customProcess : info.processName;
7812        BatteryStatsImpl.Uid.Proc ps = null;
7813        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
7814        synchronized (stats) {
7815            ps = stats.getProcessStatsLocked(info.uid, proc);
7816        }
7817        return new ProcessRecord(ps, thread, info, proc);
7818    }
7819
7820    final ProcessRecord addAppLocked(ApplicationInfo info) {
7821        ProcessRecord app = getProcessRecordLocked(info.processName, info.uid);
7822
7823        if (app == null) {
7824            app = newProcessRecordLocked(null, info, null);
7825            mProcessNames.put(info.processName, info.uid, app);
7826            updateLRUListLocked(app, true);
7827        }
7828
7829        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
7830                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
7831            app.persistent = true;
7832            app.maxAdj = CORE_SERVER_ADJ;
7833        }
7834        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
7835            mPersistentStartingProcesses.add(app);
7836            startProcessLocked(app, "added application", app.processName);
7837        }
7838
7839        return app;
7840    }
7841
7842    public void unhandledBack() {
7843        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
7844                "unhandledBack()");
7845
7846        synchronized(this) {
7847            int count = mHistory.size();
7848            if (Config.LOGD) Log.d(
7849                TAG, "Performing unhandledBack(): stack size = " + count);
7850            if (count > 1) {
7851                final long origId = Binder.clearCallingIdentity();
7852                finishActivityLocked((HistoryRecord)mHistory.get(count-1),
7853                        count-1, Activity.RESULT_CANCELED, null, "unhandled-back");
7854                Binder.restoreCallingIdentity(origId);
7855            }
7856        }
7857    }
7858
7859    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
7860        String name = uri.getAuthority();
7861        ContentProviderHolder cph = getContentProviderExternal(name);
7862        ParcelFileDescriptor pfd = null;
7863        if (cph != null) {
7864            // We record the binder invoker's uid in thread-local storage before
7865            // going to the content provider to open the file.  Later, in the code
7866            // that handles all permissions checks, we look for this uid and use
7867            // that rather than the Activity Manager's own uid.  The effect is that
7868            // we do the check against the caller's permissions even though it looks
7869            // to the content provider like the Activity Manager itself is making
7870            // the request.
7871            sCallerIdentity.set(new Identity(
7872                    Binder.getCallingPid(), Binder.getCallingUid()));
7873            try {
7874                pfd = cph.provider.openFile(uri, "r");
7875            } catch (FileNotFoundException e) {
7876                // do nothing; pfd will be returned null
7877            } finally {
7878                // Ensure that whatever happens, we clean up the identity state
7879                sCallerIdentity.remove();
7880            }
7881
7882            // We've got the fd now, so we're done with the provider.
7883            removeContentProviderExternal(name);
7884        } else {
7885            Log.d(TAG, "Failed to get provider for authority '" + name + "'");
7886        }
7887        return pfd;
7888    }
7889
7890    public void goingToSleep() {
7891        synchronized(this) {
7892            mSleeping = true;
7893            mWindowManager.setEventDispatching(false);
7894
7895            if (mResumedActivity != null) {
7896                pauseIfSleepingLocked();
7897            } else {
7898                Log.w(TAG, "goingToSleep with no resumed activity!");
7899            }
7900        }
7901    }
7902
7903    public boolean shutdown(int timeout) {
7904        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
7905                != PackageManager.PERMISSION_GRANTED) {
7906            throw new SecurityException("Requires permission "
7907                    + android.Manifest.permission.SHUTDOWN);
7908        }
7909
7910        boolean timedout = false;
7911
7912        synchronized(this) {
7913            mShuttingDown = true;
7914            mWindowManager.setEventDispatching(false);
7915
7916            if (mResumedActivity != null) {
7917                pauseIfSleepingLocked();
7918                final long endTime = System.currentTimeMillis() + timeout;
7919                while (mResumedActivity != null || mPausingActivity != null) {
7920                    long delay = endTime - System.currentTimeMillis();
7921                    if (delay <= 0) {
7922                        Log.w(TAG, "Activity manager shutdown timed out");
7923                        timedout = true;
7924                        break;
7925                    }
7926                    try {
7927                        this.wait();
7928                    } catch (InterruptedException e) {
7929                    }
7930                }
7931            }
7932        }
7933
7934        mUsageStatsService.shutdown();
7935        mBatteryStatsService.shutdown();
7936
7937        return timedout;
7938    }
7939
7940    void pauseIfSleepingLocked() {
7941        if (mSleeping || mShuttingDown) {
7942            if (!mGoingToSleep.isHeld()) {
7943                mGoingToSleep.acquire();
7944                if (mLaunchingActivity.isHeld()) {
7945                    mLaunchingActivity.release();
7946                    mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
7947                }
7948            }
7949
7950            // If we are not currently pausing an activity, get the current
7951            // one to pause.  If we are pausing one, we will just let that stuff
7952            // run and release the wake lock when all done.
7953            if (mPausingActivity == null) {
7954                if (DEBUG_PAUSE) Log.v(TAG, "Sleep needs to pause...");
7955                if (DEBUG_USER_LEAVING) Log.v(TAG, "Sleep => pause with userLeaving=false");
7956                startPausingLocked(false, true);
7957            }
7958        }
7959    }
7960
7961    public void wakingUp() {
7962        synchronized(this) {
7963            if (mGoingToSleep.isHeld()) {
7964                mGoingToSleep.release();
7965            }
7966            mWindowManager.setEventDispatching(true);
7967            mSleeping = false;
7968            resumeTopActivityLocked(null);
7969        }
7970    }
7971
7972    public void stopAppSwitches() {
7973        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
7974                != PackageManager.PERMISSION_GRANTED) {
7975            throw new SecurityException("Requires permission "
7976                    + android.Manifest.permission.STOP_APP_SWITCHES);
7977        }
7978
7979        synchronized(this) {
7980            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
7981                    + APP_SWITCH_DELAY_TIME;
7982            mDidAppSwitch = false;
7983            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
7984            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
7985            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
7986        }
7987    }
7988
7989    public void resumeAppSwitches() {
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            // Note that we don't execute any pending app switches... we will
7998            // let those wait until either the timeout, or the next start
7999            // activity request.
8000            mAppSwitchesAllowedTime = 0;
8001        }
8002    }
8003
8004    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
8005            String name) {
8006        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
8007            return true;
8008        }
8009
8010        final int perm = checkComponentPermission(
8011                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
8012                callingUid, -1);
8013        if (perm == PackageManager.PERMISSION_GRANTED) {
8014            return true;
8015        }
8016
8017        Log.w(TAG, name + " request from " + callingUid + " stopped");
8018        return false;
8019    }
8020
8021    public void setDebugApp(String packageName, boolean waitForDebugger,
8022            boolean persistent) {
8023        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
8024                "setDebugApp()");
8025
8026        // Note that this is not really thread safe if there are multiple
8027        // callers into it at the same time, but that's not a situation we
8028        // care about.
8029        if (persistent) {
8030            final ContentResolver resolver = mContext.getContentResolver();
8031            Settings.System.putString(
8032                resolver, Settings.System.DEBUG_APP,
8033                packageName);
8034            Settings.System.putInt(
8035                resolver, Settings.System.WAIT_FOR_DEBUGGER,
8036                waitForDebugger ? 1 : 0);
8037        }
8038
8039        synchronized (this) {
8040            if (!persistent) {
8041                mOrigDebugApp = mDebugApp;
8042                mOrigWaitForDebugger = mWaitForDebugger;
8043            }
8044            mDebugApp = packageName;
8045            mWaitForDebugger = waitForDebugger;
8046            mDebugTransient = !persistent;
8047            if (packageName != null) {
8048                final long origId = Binder.clearCallingIdentity();
8049                uninstallPackageLocked(packageName, -1, false);
8050                Binder.restoreCallingIdentity(origId);
8051            }
8052        }
8053    }
8054
8055    public void setAlwaysFinish(boolean enabled) {
8056        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
8057                "setAlwaysFinish()");
8058
8059        Settings.System.putInt(
8060                mContext.getContentResolver(),
8061                Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
8062
8063        synchronized (this) {
8064            mAlwaysFinishActivities = enabled;
8065        }
8066    }
8067
8068    public void setActivityController(IActivityController controller) {
8069        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8070                "setActivityController()");
8071        synchronized (this) {
8072            mController = controller;
8073        }
8074    }
8075
8076    public void registerActivityWatcher(IActivityWatcher watcher) {
8077        mWatchers.register(watcher);
8078    }
8079
8080    public void unregisterActivityWatcher(IActivityWatcher watcher) {
8081        mWatchers.unregister(watcher);
8082    }
8083
8084    public final void enterSafeMode() {
8085        synchronized(this) {
8086            // It only makes sense to do this before the system is ready
8087            // and started launching other packages.
8088            if (!mSystemReady) {
8089                try {
8090                    ActivityThread.getPackageManager().enterSafeMode();
8091                } catch (RemoteException e) {
8092                }
8093
8094                View v = LayoutInflater.from(mContext).inflate(
8095                        com.android.internal.R.layout.safe_mode, null);
8096                WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
8097                lp.type = WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY;
8098                lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
8099                lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
8100                lp.gravity = Gravity.BOTTOM | Gravity.LEFT;
8101                lp.format = v.getBackground().getOpacity();
8102                lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
8103                        | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
8104                ((WindowManager)mContext.getSystemService(
8105                        Context.WINDOW_SERVICE)).addView(v, lp);
8106            }
8107        }
8108    }
8109
8110    public void noteWakeupAlarm(IIntentSender sender) {
8111        if (!(sender instanceof PendingIntentRecord)) {
8112            return;
8113        }
8114        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8115        synchronized (stats) {
8116            if (mBatteryStatsService.isOnBattery()) {
8117                mBatteryStatsService.enforceCallingPermission();
8118                PendingIntentRecord rec = (PendingIntentRecord)sender;
8119                int MY_UID = Binder.getCallingUid();
8120                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
8121                BatteryStatsImpl.Uid.Pkg pkg =
8122                    stats.getPackageStatsLocked(uid, rec.key.packageName);
8123                pkg.incWakeupsLocked();
8124            }
8125        }
8126    }
8127
8128    public boolean killPidsForMemory(int[] pids) {
8129        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
8130            throw new SecurityException("killPidsForMemory only available to the system");
8131        }
8132
8133        // XXX Note: don't acquire main activity lock here, because the window
8134        // manager calls in with its locks held.
8135
8136        boolean killed = false;
8137        synchronized (mPidsSelfLocked) {
8138            int[] types = new int[pids.length];
8139            int worstType = 0;
8140            for (int i=0; i<pids.length; i++) {
8141                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
8142                if (proc != null) {
8143                    int type = proc.setAdj;
8144                    types[i] = type;
8145                    if (type > worstType) {
8146                        worstType = type;
8147                    }
8148                }
8149            }
8150
8151            // If the worse oom_adj is somewhere in the hidden proc LRU range,
8152            // then constrain it so we will kill all hidden procs.
8153            if (worstType < EMPTY_APP_ADJ && worstType > HIDDEN_APP_MIN_ADJ) {
8154                worstType = HIDDEN_APP_MIN_ADJ;
8155            }
8156            Log.w(TAG, "Killing processes for memory at adjustment " + worstType);
8157            for (int i=0; i<pids.length; i++) {
8158                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
8159                if (proc == null) {
8160                    continue;
8161                }
8162                int adj = proc.setAdj;
8163                if (adj >= worstType) {
8164                    Log.w(TAG, "Killing for memory: " + proc + " (adj "
8165                            + adj + ")");
8166                    EventLog.writeEvent(LOG_AM_KILL_FOR_MEMORY, proc.pid,
8167                            proc.processName, adj);
8168                    killed = true;
8169                    Process.killProcess(pids[i]);
8170                }
8171            }
8172        }
8173        return killed;
8174    }
8175
8176    public void reportPss(IApplicationThread caller, int pss) {
8177        Watchdog.PssRequestor req;
8178        String name;
8179        ProcessRecord callerApp;
8180        synchronized (this) {
8181            if (caller == null) {
8182                return;
8183            }
8184            callerApp = getRecordForAppLocked(caller);
8185            if (callerApp == null) {
8186                return;
8187            }
8188            callerApp.lastPss = pss;
8189            req = callerApp;
8190            name = callerApp.processName;
8191        }
8192        Watchdog.getInstance().reportPss(req, name, pss);
8193        if (!callerApp.persistent) {
8194            removeRequestedPss(callerApp);
8195        }
8196    }
8197
8198    public void requestPss(Runnable completeCallback) {
8199        ArrayList<ProcessRecord> procs;
8200        synchronized (this) {
8201            mRequestPssCallback = completeCallback;
8202            mRequestPssList.clear();
8203            for (int i=mLRUProcesses.size()-1; i>=0; i--) {
8204                ProcessRecord proc = mLRUProcesses.get(i);
8205                if (!proc.persistent) {
8206                    mRequestPssList.add(proc);
8207                }
8208            }
8209            procs = new ArrayList<ProcessRecord>(mRequestPssList);
8210        }
8211
8212        int oldPri = Process.getThreadPriority(Process.myTid());
8213        Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
8214        for (int i=procs.size()-1; i>=0; i--) {
8215            ProcessRecord proc = procs.get(i);
8216            proc.lastPss = 0;
8217            proc.requestPss();
8218        }
8219        Process.setThreadPriority(oldPri);
8220    }
8221
8222    void removeRequestedPss(ProcessRecord proc) {
8223        Runnable callback = null;
8224        synchronized (this) {
8225            if (mRequestPssList.remove(proc)) {
8226                if (mRequestPssList.size() == 0) {
8227                    callback = mRequestPssCallback;
8228                    mRequestPssCallback = null;
8229                }
8230            }
8231        }
8232
8233        if (callback != null) {
8234            callback.run();
8235        }
8236    }
8237
8238    public void collectPss(Watchdog.PssStats stats) {
8239        stats.mEmptyPss = 0;
8240        stats.mEmptyCount = 0;
8241        stats.mBackgroundPss = 0;
8242        stats.mBackgroundCount = 0;
8243        stats.mServicePss = 0;
8244        stats.mServiceCount = 0;
8245        stats.mVisiblePss = 0;
8246        stats.mVisibleCount = 0;
8247        stats.mForegroundPss = 0;
8248        stats.mForegroundCount = 0;
8249        stats.mNoPssCount = 0;
8250        synchronized (this) {
8251            int i;
8252            int NPD = mProcDeaths.length < stats.mProcDeaths.length
8253                    ? mProcDeaths.length : stats.mProcDeaths.length;
8254            int aggr = 0;
8255            for (i=0; i<NPD; i++) {
8256                aggr += mProcDeaths[i];
8257                stats.mProcDeaths[i] = aggr;
8258            }
8259            while (i<stats.mProcDeaths.length) {
8260                stats.mProcDeaths[i] = 0;
8261                i++;
8262            }
8263
8264            for (i=mLRUProcesses.size()-1; i>=0; i--) {
8265                ProcessRecord proc = mLRUProcesses.get(i);
8266                if (proc.persistent) {
8267                    continue;
8268                }
8269                //Log.i(TAG, "Proc " + proc + ": pss=" + proc.lastPss);
8270                if (proc.lastPss == 0) {
8271                    stats.mNoPssCount++;
8272                    continue;
8273                }
8274                if (proc.setAdj == EMPTY_APP_ADJ) {
8275                    stats.mEmptyPss += proc.lastPss;
8276                    stats.mEmptyCount++;
8277                } else if (proc.setAdj == CONTENT_PROVIDER_ADJ) {
8278                    stats.mEmptyPss += proc.lastPss;
8279                    stats.mEmptyCount++;
8280                } else if (proc.setAdj >= HIDDEN_APP_MIN_ADJ) {
8281                    stats.mBackgroundPss += proc.lastPss;
8282                    stats.mBackgroundCount++;
8283                } else if (proc.setAdj >= VISIBLE_APP_ADJ) {
8284                    stats.mVisiblePss += proc.lastPss;
8285                    stats.mVisibleCount++;
8286                } else {
8287                    stats.mForegroundPss += proc.lastPss;
8288                    stats.mForegroundCount++;
8289                }
8290            }
8291        }
8292    }
8293
8294    public final void startRunning(String pkg, String cls, String action,
8295            String data) {
8296        synchronized(this) {
8297            if (mStartRunning) {
8298                return;
8299            }
8300            mStartRunning = true;
8301            mTopComponent = pkg != null && cls != null
8302                    ? new ComponentName(pkg, cls) : null;
8303            mTopAction = action != null ? action : Intent.ACTION_MAIN;
8304            mTopData = data;
8305            if (!mSystemReady) {
8306                return;
8307            }
8308        }
8309
8310        systemReady(null);
8311    }
8312
8313    private void retrieveSettings() {
8314        final ContentResolver resolver = mContext.getContentResolver();
8315        String debugApp = Settings.System.getString(
8316            resolver, Settings.System.DEBUG_APP);
8317        boolean waitForDebugger = Settings.System.getInt(
8318            resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0;
8319        boolean alwaysFinishActivities = Settings.System.getInt(
8320            resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
8321
8322        Configuration configuration = new Configuration();
8323        Settings.System.getConfiguration(resolver, configuration);
8324
8325        synchronized (this) {
8326            mDebugApp = mOrigDebugApp = debugApp;
8327            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
8328            mAlwaysFinishActivities = alwaysFinishActivities;
8329            // This happens before any activities are started, so we can
8330            // change mConfiguration in-place.
8331            mConfiguration.updateFrom(configuration);
8332            if (DEBUG_CONFIGURATION) Log.v(TAG, "Initial config: " + mConfiguration);
8333        }
8334    }
8335
8336    public boolean testIsSystemReady() {
8337        // no need to synchronize(this) just to read & return the value
8338        return mSystemReady;
8339    }
8340
8341    public void systemReady(final Runnable goingCallback) {
8342        // In the simulator, startRunning will never have been called, which
8343        // normally sets a few crucial variables. Do it here instead.
8344        if (!Process.supportsProcesses()) {
8345            mStartRunning = true;
8346            mTopAction = Intent.ACTION_MAIN;
8347        }
8348
8349        synchronized(this) {
8350            if (mSystemReady) {
8351                if (goingCallback != null) goingCallback.run();
8352                return;
8353            }
8354
8355            // Check to see if there are any update receivers to run.
8356            if (!mDidUpdate) {
8357                if (mWaitingUpdate) {
8358                    return;
8359                }
8360                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
8361                List<ResolveInfo> ris = null;
8362                try {
8363                    ris = ActivityThread.getPackageManager().queryIntentReceivers(
8364                                intent, null, 0);
8365                } catch (RemoteException e) {
8366                }
8367                if (ris != null) {
8368                    for (int i=ris.size()-1; i>=0; i--) {
8369                        if ((ris.get(i).activityInfo.applicationInfo.flags
8370                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
8371                            ris.remove(i);
8372                        }
8373                    }
8374                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
8375                    for (int i=0; i<ris.size(); i++) {
8376                        ActivityInfo ai = ris.get(i).activityInfo;
8377                        intent.setComponent(new ComponentName(ai.packageName, ai.name));
8378                        IIntentReceiver finisher = null;
8379                        if (i == 0) {
8380                            finisher = new IIntentReceiver.Stub() {
8381                                public void performReceive(Intent intent, int resultCode,
8382                                        String data, Bundle extras, boolean ordered)
8383                                        throws RemoteException {
8384                                    synchronized (ActivityManagerService.this) {
8385                                        mDidUpdate = true;
8386                                    }
8387                                    systemReady(goingCallback);
8388                                }
8389                            };
8390                        }
8391                        Log.i(TAG, "Sending system update to: " + intent.getComponent());
8392                        broadcastIntentLocked(null, null, intent, null, finisher,
8393                                0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID);
8394                        if (i == 0) {
8395                            mWaitingUpdate = true;
8396                        }
8397                    }
8398                }
8399                if (mWaitingUpdate) {
8400                    return;
8401                }
8402                mDidUpdate = true;
8403            }
8404
8405            mSystemReady = true;
8406            if (!mStartRunning) {
8407                return;
8408            }
8409        }
8410
8411        ArrayList<ProcessRecord> procsToKill = null;
8412        synchronized(mPidsSelfLocked) {
8413            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
8414                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
8415                if (!isAllowedWhileBooting(proc.info)){
8416                    if (procsToKill == null) {
8417                        procsToKill = new ArrayList<ProcessRecord>();
8418                    }
8419                    procsToKill.add(proc);
8420                }
8421            }
8422        }
8423
8424        if (procsToKill != null) {
8425            synchronized(this) {
8426                for (int i=procsToKill.size()-1; i>=0; i--) {
8427                    ProcessRecord proc = procsToKill.get(i);
8428                    Log.i(TAG, "Removing system update proc: " + proc);
8429                    removeProcessLocked(proc, true);
8430                }
8431            }
8432        }
8433
8434        Log.i(TAG, "System now ready");
8435        EventLog.writeEvent(LOG_BOOT_PROGRESS_AMS_READY,
8436            SystemClock.uptimeMillis());
8437
8438        synchronized(this) {
8439            // Make sure we have no pre-ready processes sitting around.
8440
8441            if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
8442                ResolveInfo ri = mContext.getPackageManager()
8443                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
8444                                STOCK_PM_FLAGS);
8445                CharSequence errorMsg = null;
8446                if (ri != null) {
8447                    ActivityInfo ai = ri.activityInfo;
8448                    ApplicationInfo app = ai.applicationInfo;
8449                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
8450                        mTopAction = Intent.ACTION_FACTORY_TEST;
8451                        mTopData = null;
8452                        mTopComponent = new ComponentName(app.packageName,
8453                                ai.name);
8454                    } else {
8455                        errorMsg = mContext.getResources().getText(
8456                                com.android.internal.R.string.factorytest_not_system);
8457                    }
8458                } else {
8459                    errorMsg = mContext.getResources().getText(
8460                            com.android.internal.R.string.factorytest_no_action);
8461                }
8462                if (errorMsg != null) {
8463                    mTopAction = null;
8464                    mTopData = null;
8465                    mTopComponent = null;
8466                    Message msg = Message.obtain();
8467                    msg.what = SHOW_FACTORY_ERROR_MSG;
8468                    msg.getData().putCharSequence("msg", errorMsg);
8469                    mHandler.sendMessage(msg);
8470                }
8471            }
8472        }
8473
8474        retrieveSettings();
8475
8476        if (goingCallback != null) goingCallback.run();
8477
8478        synchronized (this) {
8479            if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
8480                try {
8481                    List apps = ActivityThread.getPackageManager().
8482                        getPersistentApplications(STOCK_PM_FLAGS);
8483                    if (apps != null) {
8484                        int N = apps.size();
8485                        int i;
8486                        for (i=0; i<N; i++) {
8487                            ApplicationInfo info
8488                                = (ApplicationInfo)apps.get(i);
8489                            if (info != null &&
8490                                    !info.packageName.equals("android")) {
8491                                addAppLocked(info);
8492                            }
8493                        }
8494                    }
8495                } catch (RemoteException ex) {
8496                    // pm is in same process, this will never happen.
8497                }
8498            }
8499
8500            // Start up initial activity.
8501            mBooting = true;
8502
8503            try {
8504                if (ActivityThread.getPackageManager().hasSystemUidErrors()) {
8505                    Message msg = Message.obtain();
8506                    msg.what = SHOW_UID_ERROR_MSG;
8507                    mHandler.sendMessage(msg);
8508                }
8509            } catch (RemoteException e) {
8510            }
8511
8512            resumeTopActivityLocked(null);
8513        }
8514    }
8515
8516    boolean makeAppCrashingLocked(ProcessRecord app,
8517            String tag, String shortMsg, String longMsg, byte[] crashData) {
8518        app.crashing = true;
8519        app.crashingReport = generateProcessError(app,
8520                ActivityManager.ProcessErrorStateInfo.CRASHED, tag, shortMsg, longMsg, crashData);
8521        startAppProblemLocked(app);
8522        app.stopFreezingAllLocked();
8523        return handleAppCrashLocked(app);
8524    }
8525
8526    private ComponentName getErrorReportReceiver(ProcessRecord app) {
8527        // check if error reporting is enabled in Gservices
8528        int enabled = Settings.Gservices.getInt(mContext.getContentResolver(),
8529                Settings.Gservices.SEND_ACTION_APP_ERROR, 0);
8530        if (enabled == 0) {
8531            return null;
8532        }
8533
8534        IPackageManager pm = ActivityThread.getPackageManager();
8535
8536        try {
8537            // look for receiver in the installer package
8538            String candidate = pm.getInstallerPackageName(app.info.packageName);
8539            ComponentName result = getErrorReportReceiver(pm, app.info.packageName, candidate);
8540            if (result != null) {
8541                return result;
8542            }
8543
8544            // if the error app is on the system image, look for system apps
8545            // error receiver
8546            if ((app.info.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
8547                candidate = SystemProperties.get(SYSTEM_APPS_ERROR_RECEIVER_PROPERTY);
8548                result = getErrorReportReceiver(pm, app.info.packageName, candidate);
8549                if (result != null) {
8550                    return result;
8551                }
8552            }
8553
8554            // if there is a default receiver, try that
8555            candidate = SystemProperties.get(DEFAULT_ERROR_RECEIVER_PROPERTY);
8556            return getErrorReportReceiver(pm, app.info.packageName, candidate);
8557        } catch (RemoteException e) {
8558            // should not happen
8559            Log.e(TAG, "error talking to PackageManager", e);
8560            return null;
8561        }
8562    }
8563
8564    /**
8565     * Return activity in receiverPackage that handles ACTION_APP_ERROR.
8566     *
8567     * @param pm PackageManager isntance
8568     * @param errorPackage package which caused the error
8569     * @param receiverPackage candidate package to receive the error
8570     * @return activity component within receiverPackage which handles
8571     * ACTION_APP_ERROR, or null if not found
8572     */
8573    private ComponentName getErrorReportReceiver(IPackageManager pm, String errorPackage,
8574            String receiverPackage) throws RemoteException {
8575        if (receiverPackage == null || receiverPackage.length() == 0) {
8576            return null;
8577        }
8578
8579        // break the loop if it's the error report receiver package that crashed
8580        if (receiverPackage.equals(errorPackage)) {
8581            return null;
8582        }
8583
8584        Intent intent = new Intent(Intent.ACTION_APP_ERROR);
8585        intent.setPackage(receiverPackage);
8586        ResolveInfo info = pm.resolveIntent(intent, null, 0);
8587        if (info == null || info.activityInfo == null) {
8588            return null;
8589        }
8590        return new ComponentName(receiverPackage, info.activityInfo.name);
8591    }
8592
8593    void makeAppNotRespondingLocked(ProcessRecord app,
8594            String tag, String shortMsg, String longMsg, byte[] crashData) {
8595        app.notResponding = true;
8596        app.notRespondingReport = generateProcessError(app,
8597                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, tag, shortMsg, longMsg,
8598                crashData);
8599        startAppProblemLocked(app);
8600        app.stopFreezingAllLocked();
8601    }
8602
8603    /**
8604     * Generate a process error record, suitable for attachment to a ProcessRecord.
8605     *
8606     * @param app The ProcessRecord in which the error occurred.
8607     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
8608     *                      ActivityManager.AppErrorStateInfo
8609     * @param tag The tag that was passed into handleApplicationError().  Typically the classname.
8610     * @param shortMsg Short message describing the crash.
8611     * @param longMsg Long message describing the crash.
8612     * @param crashData Raw data passed into handleApplicationError().  Typically a stack trace.
8613     *
8614     * @return Returns a fully-formed AppErrorStateInfo record.
8615     */
8616    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
8617            int condition, String tag, String shortMsg, String longMsg, byte[] crashData) {
8618        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
8619
8620        report.condition = condition;
8621        report.processName = app.processName;
8622        report.pid = app.pid;
8623        report.uid = app.info.uid;
8624        report.tag = tag;
8625        report.shortMsg = shortMsg;
8626        report.longMsg = longMsg;
8627        report.crashData = crashData;
8628
8629        return report;
8630    }
8631
8632    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog,
8633            boolean crashed) {
8634        synchronized (this) {
8635            app.crashing = false;
8636            app.crashingReport = null;
8637            app.notResponding = false;
8638            app.notRespondingReport = null;
8639            if (app.anrDialog == fromDialog) {
8640                app.anrDialog = null;
8641            }
8642            if (app.waitDialog == fromDialog) {
8643                app.waitDialog = null;
8644            }
8645            if (app.pid > 0 && app.pid != MY_PID) {
8646                if (crashed) {
8647                    handleAppCrashLocked(app);
8648                }
8649                Log.i(ActivityManagerService.TAG, "Killing process "
8650                        + app.processName
8651                        + " (pid=" + app.pid + ") at user's request");
8652                Process.killProcess(app.pid);
8653            }
8654
8655        }
8656    }
8657
8658    boolean handleAppCrashLocked(ProcessRecord app) {
8659        long now = SystemClock.uptimeMillis();
8660
8661        Long crashTime = mProcessCrashTimes.get(app.info.processName,
8662                app.info.uid);
8663        if (crashTime != null && now < crashTime+MIN_CRASH_INTERVAL) {
8664            // This process loses!
8665            Log.w(TAG, "Process " + app.info.processName
8666                    + " has crashed too many times: killing!");
8667            EventLog.writeEvent(LOG_AM_PROCESS_CRASHED_TOO_MUCH,
8668                    app.info.processName, app.info.uid);
8669            killServicesLocked(app, false);
8670            for (int i=mHistory.size()-1; i>=0; i--) {
8671                HistoryRecord r = (HistoryRecord)mHistory.get(i);
8672                if (r.app == app) {
8673                    if (Config.LOGD) Log.d(
8674                        TAG, "  Force finishing activity "
8675                        + r.intent.getComponent().flattenToShortString());
8676                    finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed");
8677                }
8678            }
8679            if (!app.persistent) {
8680                // We don't want to start this process again until the user
8681                // explicitly does so...  but for persistent process, we really
8682                // need to keep it running.  If a persistent process is actually
8683                // repeatedly crashing, then badness for everyone.
8684                EventLog.writeEvent(LOG_AM_PROCESS_BAD, app.info.uid,
8685                        app.info.processName);
8686                mBadProcesses.put(app.info.processName, app.info.uid, now);
8687                app.bad = true;
8688                mProcessCrashTimes.remove(app.info.processName, app.info.uid);
8689                app.removed = true;
8690                removeProcessLocked(app, false);
8691                return false;
8692            }
8693        }
8694
8695        // Bump up the crash count of any services currently running in the proc.
8696        if (app.services.size() != 0) {
8697            // Any services running in the application need to be placed
8698            // back in the pending list.
8699            Iterator it = app.services.iterator();
8700            while (it.hasNext()) {
8701                ServiceRecord sr = (ServiceRecord)it.next();
8702                sr.crashCount++;
8703            }
8704        }
8705
8706        mProcessCrashTimes.put(app.info.processName, app.info.uid, now);
8707        return true;
8708    }
8709
8710    void startAppProblemLocked(ProcessRecord app) {
8711        app.errorReportReceiver = getErrorReportReceiver(app);
8712        skipCurrentReceiverLocked(app);
8713    }
8714
8715    void skipCurrentReceiverLocked(ProcessRecord app) {
8716        boolean reschedule = false;
8717        BroadcastRecord r = app.curReceiver;
8718        if (r != null) {
8719            // The current broadcast is waiting for this app's receiver
8720            // to be finished.  Looks like that's not going to happen, so
8721            // let the broadcast continue.
8722            logBroadcastReceiverDiscard(r);
8723            finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
8724                    r.resultExtras, r.resultAbort, true);
8725            reschedule = true;
8726        }
8727        r = mPendingBroadcast;
8728        if (r != null && r.curApp == app) {
8729            if (DEBUG_BROADCAST) Log.v(TAG,
8730                    "skip & discard pending app " + r);
8731            logBroadcastReceiverDiscard(r);
8732            finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
8733                    r.resultExtras, r.resultAbort, true);
8734            reschedule = true;
8735        }
8736        if (reschedule) {
8737            scheduleBroadcastsLocked();
8738        }
8739    }
8740
8741    public int handleApplicationError(IBinder app, int flags,
8742            String tag, String shortMsg, String longMsg, byte[] crashData) {
8743        AppErrorResult result = new AppErrorResult();
8744        ProcessRecord r = null;
8745        synchronized (this) {
8746            if (app != null) {
8747                for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
8748                    final int NA = apps.size();
8749                    for (int ia=0; ia<NA; ia++) {
8750                        ProcessRecord p = apps.valueAt(ia);
8751                        if (p.thread != null && p.thread.asBinder() == app) {
8752                            r = p;
8753                            break;
8754                        }
8755                    }
8756                }
8757            }
8758
8759            if (r != null) {
8760                // The application has crashed. Send the SIGQUIT to the process so
8761                // that it can dump its state.
8762                Process.sendSignal(r.pid, Process.SIGNAL_QUIT);
8763                //Log.i(TAG, "Current system threads:");
8764                //Process.sendSignal(MY_PID, Process.SIGNAL_QUIT);
8765            }
8766
8767            if (mController != null) {
8768                try {
8769                    String name = r != null ? r.processName : null;
8770                    int pid = r != null ? r.pid : Binder.getCallingPid();
8771                    if (!mController.appCrashed(name, pid,
8772                            shortMsg, longMsg, crashData)) {
8773                        Log.w(TAG, "Force-killing crashed app " + name
8774                                + " at watcher's request");
8775                        Process.killProcess(pid);
8776                        return 0;
8777                    }
8778                } catch (RemoteException e) {
8779                    mController = null;
8780                }
8781            }
8782
8783            final long origId = Binder.clearCallingIdentity();
8784
8785            // If this process is running instrumentation, finish it.
8786            if (r != null && r.instrumentationClass != null) {
8787                Log.w(TAG, "Error in app " + r.processName
8788                      + " running instrumentation " + r.instrumentationClass + ":");
8789                if (shortMsg != null) Log.w(TAG, "  " + shortMsg);
8790                if (longMsg != null) Log.w(TAG, "  " + longMsg);
8791                Bundle info = new Bundle();
8792                info.putString("shortMsg", shortMsg);
8793                info.putString("longMsg", longMsg);
8794                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
8795                Binder.restoreCallingIdentity(origId);
8796                return 0;
8797            }
8798
8799            if (r != null) {
8800                if (!makeAppCrashingLocked(r, tag, shortMsg, longMsg, crashData)) {
8801                    return 0;
8802                }
8803            } else {
8804                Log.w(TAG, "Some application object " + app + " tag " + tag
8805                        + " has crashed, but I don't know who it is.");
8806                Log.w(TAG, "ShortMsg:" + shortMsg);
8807                Log.w(TAG, "LongMsg:" + longMsg);
8808                Binder.restoreCallingIdentity(origId);
8809                return 0;
8810            }
8811
8812            Message msg = Message.obtain();
8813            msg.what = SHOW_ERROR_MSG;
8814            HashMap data = new HashMap();
8815            data.put("result", result);
8816            data.put("app", r);
8817            data.put("flags", flags);
8818            data.put("shortMsg", shortMsg);
8819            data.put("longMsg", longMsg);
8820            if (r != null && (r.info.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
8821                // For system processes, submit crash data to the server.
8822                data.put("crashData", crashData);
8823            }
8824            msg.obj = data;
8825            mHandler.sendMessage(msg);
8826
8827            Binder.restoreCallingIdentity(origId);
8828        }
8829
8830        int res = result.get();
8831
8832        Intent appErrorIntent = null;
8833        synchronized (this) {
8834            if (r != null) {
8835                mProcessCrashTimes.put(r.info.processName, r.info.uid,
8836                        SystemClock.uptimeMillis());
8837            }
8838            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
8839                appErrorIntent = createAppErrorIntentLocked(r);
8840                res = AppErrorDialog.FORCE_QUIT;
8841            }
8842        }
8843
8844        if (appErrorIntent != null) {
8845            try {
8846                mContext.startActivity(appErrorIntent);
8847            } catch (ActivityNotFoundException e) {
8848                Log.w(TAG, "bug report receiver dissappeared", e);
8849            }
8850        }
8851
8852        return res;
8853    }
8854
8855    Intent createAppErrorIntentLocked(ProcessRecord r) {
8856        ApplicationErrorReport report = createAppErrorReportLocked(r);
8857        if (report == null) {
8858            return null;
8859        }
8860        Intent result = new Intent(Intent.ACTION_APP_ERROR);
8861        result.setComponent(r.errorReportReceiver);
8862        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
8863        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8864        return result;
8865    }
8866
8867    ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r) {
8868        if (r.errorReportReceiver == null) {
8869            return null;
8870        }
8871
8872        if (!r.crashing && !r.notResponding) {
8873            return null;
8874        }
8875
8876        try {
8877            ApplicationErrorReport report = new ApplicationErrorReport();
8878            report.packageName = r.info.packageName;
8879            report.installerPackageName = r.errorReportReceiver.getPackageName();
8880            report.processName = r.processName;
8881
8882            if (r.crashing) {
8883                report.type = ApplicationErrorReport.TYPE_CRASH;
8884                report.crashInfo = new ApplicationErrorReport.CrashInfo();
8885
8886                ByteArrayInputStream byteStream = new ByteArrayInputStream(
8887                        r.crashingReport.crashData);
8888                DataInputStream dataStream = new DataInputStream(byteStream);
8889                CrashData crashData = new CrashData(dataStream);
8890                ThrowableData throwData = crashData.getThrowableData();
8891
8892                report.time = crashData.getTime();
8893                report.crashInfo.stackTrace = throwData.toString();
8894
8895                // Extract the source of the exception, useful for report
8896                // clustering. Also extract the "deepest" non-null exception
8897                // message.
8898                String exceptionMessage = throwData.getMessage();
8899                while (throwData.getCause() != null) {
8900                    throwData = throwData.getCause();
8901                    String msg = throwData.getMessage();
8902                    if (msg != null && msg.length() > 0) {
8903                       exceptionMessage = msg;
8904                    }
8905                }
8906                StackTraceElementData trace = throwData.getStackTrace()[0];
8907                report.crashInfo.exceptionMessage = exceptionMessage;
8908                report.crashInfo.exceptionClassName = throwData.getType();
8909                report.crashInfo.throwFileName = trace.getFileName();
8910                report.crashInfo.throwClassName = trace.getClassName();
8911                report.crashInfo.throwMethodName = trace.getMethodName();
8912                report.crashInfo.throwLineNumber = trace.getLineNumber();
8913            } else if (r.notResponding) {
8914                report.type = ApplicationErrorReport.TYPE_ANR;
8915                report.anrInfo = new ApplicationErrorReport.AnrInfo();
8916
8917                report.anrInfo.activity = r.notRespondingReport.tag;
8918                report.anrInfo.cause = r.notRespondingReport.shortMsg;
8919                report.anrInfo.info = r.notRespondingReport.longMsg;
8920            }
8921
8922            return report;
8923        } catch (IOException e) {
8924            // we don't send it
8925        }
8926
8927        return null;
8928    }
8929
8930    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
8931        // assume our apps are happy - lazy create the list
8932        List<ActivityManager.ProcessErrorStateInfo> errList = null;
8933
8934        synchronized (this) {
8935
8936            // iterate across all processes
8937            final int N = mLRUProcesses.size();
8938            for (int i = 0; i < N; i++) {
8939                ProcessRecord app = mLRUProcesses.get(i);
8940                if ((app.thread != null) && (app.crashing || app.notResponding)) {
8941                    // This one's in trouble, so we'll generate a report for it
8942                    // crashes are higher priority (in case there's a crash *and* an anr)
8943                    ActivityManager.ProcessErrorStateInfo report = null;
8944                    if (app.crashing) {
8945                        report = app.crashingReport;
8946                    } else if (app.notResponding) {
8947                        report = app.notRespondingReport;
8948                    }
8949
8950                    if (report != null) {
8951                        if (errList == null) {
8952                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
8953                        }
8954                        errList.add(report);
8955                    } else {
8956                        Log.w(TAG, "Missing app error report, app = " + app.processName +
8957                                " crashing = " + app.crashing +
8958                                " notResponding = " + app.notResponding);
8959                    }
8960                }
8961            }
8962        }
8963
8964        return errList;
8965    }
8966
8967    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
8968        // Lazy instantiation of list
8969        List<ActivityManager.RunningAppProcessInfo> runList = null;
8970        synchronized (this) {
8971            // Iterate across all processes
8972            final int N = mLRUProcesses.size();
8973            for (int i = 0; i < N; i++) {
8974                ProcessRecord app = mLRUProcesses.get(i);
8975                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
8976                    // Generate process state info for running application
8977                    ActivityManager.RunningAppProcessInfo currApp =
8978                        new ActivityManager.RunningAppProcessInfo(app.processName,
8979                                app.pid, app.getPackageList());
8980                    currApp.uid = app.info.uid;
8981                    int adj = app.curAdj;
8982                    if (adj >= CONTENT_PROVIDER_ADJ) {
8983                        currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_EMPTY;
8984                    } else if (adj >= HIDDEN_APP_MIN_ADJ) {
8985                        currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
8986                        currApp.lru = adj - HIDDEN_APP_MIN_ADJ + 1;
8987                    } else if (adj >= HOME_APP_ADJ) {
8988                        currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
8989                        currApp.lru = 0;
8990                    } else if (adj >= SECONDARY_SERVER_ADJ) {
8991                        currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
8992                    } else if (adj >= VISIBLE_APP_ADJ) {
8993                        currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
8994                    } else {
8995                        currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
8996                    }
8997                    currApp.importanceReasonCode = app.adjTypeCode;
8998                    if (app.adjSource instanceof ProcessRecord) {
8999                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
9000                    } else if (app.adjSource instanceof HistoryRecord) {
9001                        HistoryRecord r = (HistoryRecord)app.adjSource;
9002                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
9003                    }
9004                    if (app.adjTarget instanceof ComponentName) {
9005                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
9006                    }
9007                    //Log.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
9008                    //        + " lru=" + currApp.lru);
9009                    if (runList == null) {
9010                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
9011                    }
9012                    runList.add(currApp);
9013                }
9014            }
9015        }
9016        return runList;
9017    }
9018
9019    @Override
9020    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
9021        synchronized (this) {
9022            if (checkCallingPermission(android.Manifest.permission.DUMP)
9023                    != PackageManager.PERMISSION_GRANTED) {
9024                pw.println("Permission Denial: can't dump ActivityManager from from pid="
9025                        + Binder.getCallingPid()
9026                        + ", uid=" + Binder.getCallingUid()
9027                        + " without permission "
9028                        + android.Manifest.permission.DUMP);
9029                return;
9030            }
9031            if (args.length != 0 && "service".equals(args[0])) {
9032                dumpService(fd, pw, args);
9033                return;
9034            }
9035            pw.println("Activities in Current Activity Manager State:");
9036            dumpHistoryList(pw, mHistory, "  ", "Hist", true);
9037            pw.println(" ");
9038            pw.println("  Running activities (most recent first):");
9039            dumpHistoryList(pw, mLRUActivities, "  ", "Run", false);
9040            if (mWaitingVisibleActivities.size() > 0) {
9041                pw.println(" ");
9042                pw.println("  Activities waiting for another to become visible:");
9043                dumpHistoryList(pw, mWaitingVisibleActivities, "  ", "Wait", false);
9044            }
9045            if (mStoppingActivities.size() > 0) {
9046                pw.println(" ");
9047                pw.println("  Activities waiting to stop:");
9048                dumpHistoryList(pw, mStoppingActivities, "  ", "Stop", false);
9049            }
9050            if (mFinishingActivities.size() > 0) {
9051                pw.println(" ");
9052                pw.println("  Activities waiting to finish:");
9053                dumpHistoryList(pw, mFinishingActivities, "  ", "Fin", false);
9054            }
9055
9056            pw.println(" ");
9057            pw.println("  mPausingActivity: " + mPausingActivity);
9058            pw.println("  mResumedActivity: " + mResumedActivity);
9059            pw.println("  mFocusedActivity: " + mFocusedActivity);
9060            pw.println("  mLastPausedActivity: " + mLastPausedActivity);
9061
9062            if (mRecentTasks.size() > 0) {
9063                pw.println(" ");
9064                pw.println("Recent tasks in Current Activity Manager State:");
9065
9066                final int N = mRecentTasks.size();
9067                for (int i=0; i<N; i++) {
9068                    TaskRecord tr = mRecentTasks.get(i);
9069                    pw.print("  * Recent #"); pw.print(i); pw.print(": ");
9070                            pw.println(tr);
9071                    mRecentTasks.get(i).dump(pw, "    ");
9072                }
9073            }
9074
9075            pw.println(" ");
9076            pw.println("  mCurTask: " + mCurTask);
9077
9078            pw.println(" ");
9079            pw.println("Processes in Current Activity Manager State:");
9080
9081            boolean needSep = false;
9082            int numPers = 0;
9083
9084            for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
9085                final int NA = procs.size();
9086                for (int ia=0; ia<NA; ia++) {
9087                    if (!needSep) {
9088                        pw.println("  All known processes:");
9089                        needSep = true;
9090                    }
9091                    ProcessRecord r = procs.valueAt(ia);
9092                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
9093                        pw.print(" UID "); pw.print(procs.keyAt(ia));
9094                        pw.print(" "); pw.println(r);
9095                    r.dump(pw, "    ");
9096                    if (r.persistent) {
9097                        numPers++;
9098                    }
9099                }
9100            }
9101
9102            if (mLRUProcesses.size() > 0) {
9103                if (needSep) pw.println(" ");
9104                needSep = true;
9105                pw.println("  Running processes (most recent first):");
9106                dumpProcessList(pw, mLRUProcesses, "    ",
9107                        "App ", "PERS", true);
9108                needSep = true;
9109            }
9110
9111            synchronized (mPidsSelfLocked) {
9112                if (mPidsSelfLocked.size() > 0) {
9113                    if (needSep) pw.println(" ");
9114                    needSep = true;
9115                    pw.println("  PID mappings:");
9116                    for (int i=0; i<mPidsSelfLocked.size(); i++) {
9117                        pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
9118                            pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
9119                    }
9120                }
9121            }
9122
9123            if (mForegroundProcesses.size() > 0) {
9124                if (needSep) pw.println(" ");
9125                needSep = true;
9126                pw.println("  Foreground Processes:");
9127                for (int i=0; i<mForegroundProcesses.size(); i++) {
9128                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
9129                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
9130                }
9131            }
9132
9133            if (mPersistentStartingProcesses.size() > 0) {
9134                if (needSep) pw.println(" ");
9135                needSep = true;
9136                pw.println("  Persisent processes that are starting:");
9137                dumpProcessList(pw, mPersistentStartingProcesses, "    ",
9138                        "Starting Norm", "Restarting PERS", false);
9139            }
9140
9141            if (mStartingProcesses.size() > 0) {
9142                if (needSep) pw.println(" ");
9143                needSep = true;
9144                pw.println("  Processes that are starting:");
9145                dumpProcessList(pw, mStartingProcesses, "    ",
9146                        "Starting Norm", "Starting PERS", false);
9147            }
9148
9149            if (mRemovedProcesses.size() > 0) {
9150                if (needSep) pw.println(" ");
9151                needSep = true;
9152                pw.println("  Processes that are being removed:");
9153                dumpProcessList(pw, mRemovedProcesses, "    ",
9154                        "Removed Norm", "Removed PERS", false);
9155            }
9156
9157            if (mProcessesOnHold.size() > 0) {
9158                if (needSep) pw.println(" ");
9159                needSep = true;
9160                pw.println("  Processes that are on old until the system is ready:");
9161                dumpProcessList(pw, mProcessesOnHold, "    ",
9162                        "OnHold Norm", "OnHold PERS", false);
9163            }
9164
9165            if (mProcessesToGc.size() > 0) {
9166                if (needSep) pw.println(" ");
9167                needSep = true;
9168                pw.println("  Processes that are waiting to GC:");
9169                long now = SystemClock.uptimeMillis();
9170                for (int i=0; i<mProcessesToGc.size(); i++) {
9171                    ProcessRecord proc = mProcessesToGc.get(i);
9172                    pw.print("    Process "); pw.println(proc);
9173                    pw.print("      lowMem="); pw.print(proc.reportLowMemory);
9174                            pw.print(", last gced=");
9175                            pw.print(now-proc.lastRequestedGc);
9176                            pw.print(" ms ago, last lowMwm=");
9177                            pw.print(now-proc.lastLowMemory);
9178                            pw.println(" ms ago");
9179
9180                }
9181            }
9182
9183            if (mProcessCrashTimes.getMap().size() > 0) {
9184                if (needSep) pw.println(" ");
9185                needSep = true;
9186                pw.println("  Time since processes crashed:");
9187                long now = SystemClock.uptimeMillis();
9188                for (Map.Entry<String, SparseArray<Long>> procs
9189                        : mProcessCrashTimes.getMap().entrySet()) {
9190                    SparseArray<Long> uids = procs.getValue();
9191                    final int N = uids.size();
9192                    for (int i=0; i<N; i++) {
9193                        pw.print("    Process "); pw.print(procs.getKey());
9194                                pw.print(" uid "); pw.print(uids.keyAt(i));
9195                                pw.print(": last crashed ");
9196                                pw.print((now-uids.valueAt(i)));
9197                                pw.println(" ms ago");
9198                    }
9199                }
9200            }
9201
9202            if (mBadProcesses.getMap().size() > 0) {
9203                if (needSep) pw.println(" ");
9204                needSep = true;
9205                pw.println("  Bad processes:");
9206                for (Map.Entry<String, SparseArray<Long>> procs
9207                        : mBadProcesses.getMap().entrySet()) {
9208                    SparseArray<Long> uids = procs.getValue();
9209                    final int N = uids.size();
9210                    for (int i=0; i<N; i++) {
9211                        pw.print("    Bad process "); pw.print(procs.getKey());
9212                                pw.print(" uid "); pw.print(uids.keyAt(i));
9213                                pw.print(": crashed at time ");
9214                                pw.println(uids.valueAt(i));
9215                    }
9216                }
9217            }
9218
9219            pw.println(" ");
9220            pw.println("  Total persistent processes: " + numPers);
9221            pw.println("  mHomeProcess: " + mHomeProcess);
9222            pw.println("  mConfiguration: " + mConfiguration);
9223            pw.println("  mStartRunning=" + mStartRunning
9224                    + " mSystemReady=" + mSystemReady
9225                    + " mBooting=" + mBooting
9226                    + " mBooted=" + mBooted
9227                    + " mFactoryTest=" + mFactoryTest);
9228            pw.println("  mSleeping=" + mSleeping + " mShuttingDown=" + mShuttingDown);
9229            pw.println("  mGoingToSleep=" + mGoingToSleep);
9230            pw.println("  mLaunchingActivity=" + mLaunchingActivity);
9231            pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
9232                    + " mDebugTransient=" + mDebugTransient
9233                    + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
9234            pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
9235                    + " mController=" + mController);
9236        }
9237    }
9238
9239    /**
9240     * There are three ways to call this:
9241     *  - no service specified: dump all the services
9242     *  - a flattened component name that matched an existing service was specified as the
9243     *    first arg: dump that one service
9244     *  - the first arg isn't the flattened component name of an existing service:
9245     *    dump all services whose component contains the first arg as a substring
9246     */
9247    protected void dumpService(FileDescriptor fd, PrintWriter pw, String[] args) {
9248        String[] newArgs;
9249        String componentNameString;
9250        ServiceRecord r;
9251        if (args.length == 1) {
9252            componentNameString = null;
9253            newArgs = EMPTY_STRING_ARRAY;
9254            r = null;
9255        } else {
9256            componentNameString = args[1];
9257            ComponentName componentName = ComponentName.unflattenFromString(componentNameString);
9258            r = componentName != null ? mServices.get(componentName) : null;
9259            newArgs = new String[args.length - 2];
9260            if (args.length > 2) System.arraycopy(args, 2, newArgs, 0, args.length - 2);
9261        }
9262
9263        if (r != null) {
9264            dumpService(fd, pw, r, newArgs);
9265        } else {
9266            for (ServiceRecord r1 : mServices.values()) {
9267                if (componentNameString == null
9268                        || r1.name.flattenToString().contains(componentNameString)) {
9269                    dumpService(fd, pw, r1, newArgs);
9270                }
9271            }
9272        }
9273    }
9274
9275    /**
9276     * Invokes IApplicationThread.dumpService() on the thread of the specified service if
9277     * there is a thread associated with the service.
9278     */
9279    private void dumpService(FileDescriptor fd, PrintWriter pw, ServiceRecord r, String[] args) {
9280        pw.println("  Service " + r.name.flattenToString());
9281        if (r.app != null && r.app.thread != null) {
9282            try {
9283                // flush anything that is already in the PrintWriter since the thread is going
9284                // to write to the file descriptor directly
9285                pw.flush();
9286                r.app.thread.dumpService(fd, r, args);
9287                pw.print("\n");
9288            } catch (RemoteException e) {
9289                pw.println("got a RemoteException while dumping the service");
9290            }
9291        }
9292    }
9293
9294    void dumpBroadcasts(PrintWriter pw) {
9295        synchronized (this) {
9296            if (checkCallingPermission(android.Manifest.permission.DUMP)
9297                    != PackageManager.PERMISSION_GRANTED) {
9298                pw.println("Permission Denial: can't dump ActivityManager from from pid="
9299                        + Binder.getCallingPid()
9300                        + ", uid=" + Binder.getCallingUid()
9301                        + " without permission "
9302                        + android.Manifest.permission.DUMP);
9303                return;
9304            }
9305            pw.println("Broadcasts in Current Activity Manager State:");
9306
9307            if (mRegisteredReceivers.size() > 0) {
9308                pw.println(" ");
9309                pw.println("  Registered Receivers:");
9310                Iterator it = mRegisteredReceivers.values().iterator();
9311                while (it.hasNext()) {
9312                    ReceiverList r = (ReceiverList)it.next();
9313                    pw.print("  * "); pw.println(r);
9314                    r.dump(pw, "    ");
9315                }
9316            }
9317
9318            pw.println(" ");
9319            pw.println("Receiver Resolver Table:");
9320            mReceiverResolver.dump(pw, "  ");
9321
9322            if (mParallelBroadcasts.size() > 0 || mOrderedBroadcasts.size() > 0
9323                    || mPendingBroadcast != null) {
9324                if (mParallelBroadcasts.size() > 0) {
9325                    pw.println(" ");
9326                    pw.println("  Active broadcasts:");
9327                }
9328                for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
9329                    pw.println("  Broadcast #" + i + ":");
9330                    mParallelBroadcasts.get(i).dump(pw, "    ");
9331                }
9332                if (mOrderedBroadcasts.size() > 0) {
9333                    pw.println(" ");
9334                    pw.println("  Active serialized broadcasts:");
9335                }
9336                for (int i=mOrderedBroadcasts.size()-1; i>=0; i--) {
9337                    pw.println("  Serialized Broadcast #" + i + ":");
9338                    mOrderedBroadcasts.get(i).dump(pw, "    ");
9339                }
9340                pw.println(" ");
9341                pw.println("  Pending broadcast:");
9342                if (mPendingBroadcast != null) {
9343                    mPendingBroadcast.dump(pw, "    ");
9344                } else {
9345                    pw.println("    (null)");
9346                }
9347            }
9348
9349            pw.println(" ");
9350            pw.println("  mBroadcastsScheduled=" + mBroadcastsScheduled);
9351            if (mStickyBroadcasts != null) {
9352                pw.println(" ");
9353                pw.println("  Sticky broadcasts:");
9354                StringBuilder sb = new StringBuilder(128);
9355                for (Map.Entry<String, ArrayList<Intent>> ent
9356                        : mStickyBroadcasts.entrySet()) {
9357                    pw.print("  * Sticky action "); pw.print(ent.getKey());
9358                            pw.println(":");
9359                    ArrayList<Intent> intents = ent.getValue();
9360                    final int N = intents.size();
9361                    for (int i=0; i<N; i++) {
9362                        sb.setLength(0);
9363                        sb.append("    Intent: ");
9364                        intents.get(i).toShortString(sb, true, false);
9365                        pw.println(sb.toString());
9366                        Bundle bundle = intents.get(i).getExtras();
9367                        if (bundle != null) {
9368                            pw.print("      ");
9369                            pw.println(bundle.toString());
9370                        }
9371                    }
9372                }
9373            }
9374
9375            pw.println(" ");
9376            pw.println("  mHandler:");
9377            mHandler.dump(new PrintWriterPrinter(pw), "    ");
9378        }
9379    }
9380
9381    void dumpServices(PrintWriter pw) {
9382        synchronized (this) {
9383            if (checkCallingPermission(android.Manifest.permission.DUMP)
9384                    != PackageManager.PERMISSION_GRANTED) {
9385                pw.println("Permission Denial: can't dump ActivityManager from from pid="
9386                        + Binder.getCallingPid()
9387                        + ", uid=" + Binder.getCallingUid()
9388                        + " without permission "
9389                        + android.Manifest.permission.DUMP);
9390                return;
9391            }
9392            pw.println("Services in Current Activity Manager State:");
9393
9394            boolean needSep = false;
9395
9396            if (mServices.size() > 0) {
9397                pw.println("  Active services:");
9398                Iterator<ServiceRecord> it = mServices.values().iterator();
9399                while (it.hasNext()) {
9400                    ServiceRecord r = it.next();
9401                    pw.print("  * "); pw.println(r);
9402                    r.dump(pw, "    ");
9403                }
9404                needSep = true;
9405            }
9406
9407            if (mPendingServices.size() > 0) {
9408                if (needSep) pw.println(" ");
9409                pw.println("  Pending services:");
9410                for (int i=0; i<mPendingServices.size(); i++) {
9411                    ServiceRecord r = mPendingServices.get(i);
9412                    pw.print("  * Pending "); pw.println(r);
9413                    r.dump(pw, "    ");
9414                }
9415                needSep = true;
9416            }
9417
9418            if (mRestartingServices.size() > 0) {
9419                if (needSep) pw.println(" ");
9420                pw.println("  Restarting services:");
9421                for (int i=0; i<mRestartingServices.size(); i++) {
9422                    ServiceRecord r = mRestartingServices.get(i);
9423                    pw.print("  * Restarting "); pw.println(r);
9424                    r.dump(pw, "    ");
9425                }
9426                needSep = true;
9427            }
9428
9429            if (mStoppingServices.size() > 0) {
9430                if (needSep) pw.println(" ");
9431                pw.println("  Stopping services:");
9432                for (int i=0; i<mStoppingServices.size(); i++) {
9433                    ServiceRecord r = mStoppingServices.get(i);
9434                    pw.print("  * Stopping "); pw.println(r);
9435                    r.dump(pw, "    ");
9436                }
9437                needSep = true;
9438            }
9439
9440            if (mServiceConnections.size() > 0) {
9441                if (needSep) pw.println(" ");
9442                pw.println("  Connection bindings to services:");
9443                Iterator<ConnectionRecord> it
9444                        = mServiceConnections.values().iterator();
9445                while (it.hasNext()) {
9446                    ConnectionRecord r = it.next();
9447                    pw.print("  * "); pw.println(r);
9448                    r.dump(pw, "    ");
9449                }
9450            }
9451        }
9452    }
9453
9454    void dumpProviders(PrintWriter pw) {
9455        synchronized (this) {
9456            if (checkCallingPermission(android.Manifest.permission.DUMP)
9457                    != PackageManager.PERMISSION_GRANTED) {
9458                pw.println("Permission Denial: can't dump ActivityManager from from pid="
9459                        + Binder.getCallingPid()
9460                        + ", uid=" + Binder.getCallingUid()
9461                        + " without permission "
9462                        + android.Manifest.permission.DUMP);
9463                return;
9464            }
9465
9466            pw.println("Content Providers in Current Activity Manager State:");
9467
9468            boolean needSep = false;
9469
9470            if (mProvidersByClass.size() > 0) {
9471                if (needSep) pw.println(" ");
9472                pw.println("  Published content providers (by class):");
9473                Iterator it = mProvidersByClass.entrySet().iterator();
9474                while (it.hasNext()) {
9475                    Map.Entry e = (Map.Entry)it.next();
9476                    ContentProviderRecord r = (ContentProviderRecord)e.getValue();
9477                    pw.print("  * "); pw.println(r);
9478                    r.dump(pw, "    ");
9479                }
9480                needSep = true;
9481            }
9482
9483            if (mProvidersByName.size() > 0) {
9484                pw.println(" ");
9485                pw.println("  Authority to provider mappings:");
9486                Iterator it = mProvidersByName.entrySet().iterator();
9487                while (it.hasNext()) {
9488                    Map.Entry e = (Map.Entry)it.next();
9489                    ContentProviderRecord r = (ContentProviderRecord)e.getValue();
9490                    pw.print("  "); pw.print(e.getKey()); pw.print(": ");
9491                            pw.println(r);
9492                }
9493                needSep = true;
9494            }
9495
9496            if (mLaunchingProviders.size() > 0) {
9497                if (needSep) pw.println(" ");
9498                pw.println("  Launching content providers:");
9499                for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
9500                    pw.print("  Launching #"); pw.print(i); pw.print(": ");
9501                            pw.println(mLaunchingProviders.get(i));
9502                }
9503                needSep = true;
9504            }
9505
9506            if (mGrantedUriPermissions.size() > 0) {
9507                pw.println();
9508                pw.println("Granted Uri Permissions:");
9509                for (int i=0; i<mGrantedUriPermissions.size(); i++) {
9510                    int uid = mGrantedUriPermissions.keyAt(i);
9511                    HashMap<Uri, UriPermission> perms
9512                            = mGrantedUriPermissions.valueAt(i);
9513                    pw.print("  * UID "); pw.print(uid);
9514                            pw.println(" holds:");
9515                    for (UriPermission perm : perms.values()) {
9516                        pw.print("    "); pw.println(perm);
9517                        perm.dump(pw, "      ");
9518                    }
9519                }
9520            }
9521        }
9522    }
9523
9524    void dumpSenders(PrintWriter pw) {
9525        synchronized (this) {
9526            if (checkCallingPermission(android.Manifest.permission.DUMP)
9527                    != PackageManager.PERMISSION_GRANTED) {
9528                pw.println("Permission Denial: can't dump ActivityManager from from pid="
9529                        + Binder.getCallingPid()
9530                        + ", uid=" + Binder.getCallingUid()
9531                        + " without permission "
9532                        + android.Manifest.permission.DUMP);
9533                return;
9534            }
9535
9536            pw.println("Pending Intents in Current Activity Manager State:");
9537
9538            if (this.mIntentSenderRecords.size() > 0) {
9539                Iterator<WeakReference<PendingIntentRecord>> it
9540                        = mIntentSenderRecords.values().iterator();
9541                while (it.hasNext()) {
9542                    WeakReference<PendingIntentRecord> ref = it.next();
9543                    PendingIntentRecord rec = ref != null ? ref.get(): null;
9544                    if (rec != null) {
9545                        pw.print("  * "); pw.println(rec);
9546                        rec.dump(pw, "    ");
9547                    } else {
9548                        pw.print("  * "); pw.print(ref);
9549                    }
9550                }
9551            }
9552        }
9553    }
9554
9555    private static final void dumpHistoryList(PrintWriter pw, List list,
9556            String prefix, String label, boolean complete) {
9557        TaskRecord lastTask = null;
9558        for (int i=list.size()-1; i>=0; i--) {
9559            HistoryRecord r = (HistoryRecord)list.get(i);
9560            final boolean full = complete || !r.inHistory;
9561            if (lastTask != r.task) {
9562                lastTask = r.task;
9563                pw.print(prefix);
9564                pw.print(full ? "* " : "  ");
9565                pw.println(lastTask);
9566                if (full) {
9567                    lastTask.dump(pw, prefix + "  ");
9568                }
9569            }
9570            pw.print(prefix); pw.print(full ? "  * " : "    "); pw.print(label);
9571            pw.print(" #"); pw.print(i); pw.print(": ");
9572            pw.println(r);
9573            if (full) {
9574                r.dump(pw, prefix + "      ");
9575            }
9576        }
9577    }
9578
9579    private static final int dumpProcessList(PrintWriter pw, List list,
9580            String prefix, String normalLabel, String persistentLabel,
9581            boolean inclOomAdj) {
9582        int numPers = 0;
9583        for (int i=list.size()-1; i>=0; i--) {
9584            ProcessRecord r = (ProcessRecord)list.get(i);
9585            if (false) {
9586                pw.println(prefix + (r.persistent ? persistentLabel : normalLabel)
9587                      + " #" + i + ":");
9588                r.dump(pw, prefix + "  ");
9589            } else if (inclOomAdj) {
9590                pw.println(String.format("%s%s #%2d: adj=%4d/%d %s (%s)",
9591                        prefix, (r.persistent ? persistentLabel : normalLabel),
9592                        i, r.setAdj, r.setSchedGroup, r.toString(), r.adjType));
9593                if (r.adjSource != null || r.adjTarget != null) {
9594                    pw.println(prefix + "          " + r.adjTarget
9595                            + " used by " + r.adjSource);
9596                }
9597            } else {
9598                pw.println(String.format("%s%s #%2d: %s",
9599                        prefix, (r.persistent ? persistentLabel : normalLabel),
9600                        i, r.toString()));
9601            }
9602            if (r.persistent) {
9603                numPers++;
9604            }
9605        }
9606        return numPers;
9607    }
9608
9609    private static final void dumpApplicationMemoryUsage(FileDescriptor fd,
9610            PrintWriter pw, List list, String prefix, String[] args) {
9611        final boolean isCheckinRequest = scanArgs(args, "--checkin");
9612        long uptime = SystemClock.uptimeMillis();
9613        long realtime = SystemClock.elapsedRealtime();
9614
9615        if (isCheckinRequest) {
9616            // short checkin version
9617            pw.println(uptime + "," + realtime);
9618            pw.flush();
9619        } else {
9620            pw.println("Applications Memory Usage (kB):");
9621            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
9622        }
9623        for (int i = list.size() - 1 ; i >= 0 ; i--) {
9624            ProcessRecord r = (ProcessRecord)list.get(i);
9625            if (r.thread != null) {
9626                if (!isCheckinRequest) {
9627                    pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
9628                    pw.flush();
9629                }
9630                try {
9631                    r.thread.asBinder().dump(fd, args);
9632                } catch (RemoteException e) {
9633                    if (!isCheckinRequest) {
9634                        pw.println("Got RemoteException!");
9635                        pw.flush();
9636                    }
9637                }
9638            }
9639        }
9640    }
9641
9642    /**
9643     * Searches array of arguments for the specified string
9644     * @param args array of argument strings
9645     * @param value value to search for
9646     * @return true if the value is contained in the array
9647     */
9648    private static boolean scanArgs(String[] args, String value) {
9649        if (args != null) {
9650            for (String arg : args) {
9651                if (value.equals(arg)) {
9652                    return true;
9653                }
9654            }
9655        }
9656        return false;
9657    }
9658
9659    private final int indexOfTokenLocked(IBinder token) {
9660        int count = mHistory.size();
9661
9662        // convert the token to an entry in the history.
9663        HistoryRecord r = null;
9664        int index = -1;
9665        for (int i=count-1; i>=0; i--) {
9666            Object o = mHistory.get(i);
9667            if (o == token) {
9668                r = (HistoryRecord)o;
9669                index = i;
9670                break;
9671            }
9672        }
9673
9674        return index;
9675    }
9676
9677    private final void killServicesLocked(ProcessRecord app,
9678            boolean allowRestart) {
9679        // Report disconnected services.
9680        if (false) {
9681            // XXX we are letting the client link to the service for
9682            // death notifications.
9683            if (app.services.size() > 0) {
9684                Iterator it = app.services.iterator();
9685                while (it.hasNext()) {
9686                    ServiceRecord r = (ServiceRecord)it.next();
9687                    if (r.connections.size() > 0) {
9688                        Iterator<ConnectionRecord> jt
9689                                = r.connections.values().iterator();
9690                        while (jt.hasNext()) {
9691                            ConnectionRecord c = jt.next();
9692                            if (c.binding.client != app) {
9693                                try {
9694                                    //c.conn.connected(r.className, null);
9695                                } catch (Exception e) {
9696                                    // todo: this should be asynchronous!
9697                                    Log.w(TAG, "Exception thrown disconnected servce "
9698                                          + r.shortName
9699                                          + " from app " + app.processName, e);
9700                                }
9701                            }
9702                        }
9703                    }
9704                }
9705            }
9706        }
9707
9708        // Clean up any connections this application has to other services.
9709        if (app.connections.size() > 0) {
9710            Iterator<ConnectionRecord> it = app.connections.iterator();
9711            while (it.hasNext()) {
9712                ConnectionRecord r = it.next();
9713                removeConnectionLocked(r, app, null);
9714            }
9715        }
9716        app.connections.clear();
9717
9718        if (app.services.size() != 0) {
9719            // Any services running in the application need to be placed
9720            // back in the pending list.
9721            Iterator it = app.services.iterator();
9722            while (it.hasNext()) {
9723                ServiceRecord sr = (ServiceRecord)it.next();
9724                synchronized (sr.stats.getBatteryStats()) {
9725                    sr.stats.stopLaunchedLocked();
9726                }
9727                sr.app = null;
9728                sr.executeNesting = 0;
9729                mStoppingServices.remove(sr);
9730
9731                boolean hasClients = sr.bindings.size() > 0;
9732                if (hasClients) {
9733                    Iterator<IntentBindRecord> bindings
9734                            = sr.bindings.values().iterator();
9735                    while (bindings.hasNext()) {
9736                        IntentBindRecord b = bindings.next();
9737                        if (DEBUG_SERVICE) Log.v(TAG, "Killing binding " + b
9738                                + ": shouldUnbind=" + b.hasBound);
9739                        b.binder = null;
9740                        b.requested = b.received = b.hasBound = false;
9741                    }
9742                }
9743
9744                if (sr.crashCount >= 2) {
9745                    Log.w(TAG, "Service crashed " + sr.crashCount
9746                            + " times, stopping: " + sr);
9747                    EventLog.writeEvent(LOG_AM_SERVICE_CRASHED_TOO_MUCH,
9748                            sr.crashCount, sr.shortName, app.pid);
9749                    bringDownServiceLocked(sr, true);
9750                } else if (!allowRestart) {
9751                    bringDownServiceLocked(sr, true);
9752                } else {
9753                    boolean canceled = scheduleServiceRestartLocked(sr, true);
9754
9755                    // Should the service remain running?  Note that in the
9756                    // extreme case of so many attempts to deliver a command
9757                    // that it failed, that we also will stop it here.
9758                    if (sr.startRequested && (sr.stopIfKilled || canceled)) {
9759                        if (sr.pendingStarts.size() == 0) {
9760                            sr.startRequested = false;
9761                            if (!hasClients) {
9762                                // Whoops, no reason to restart!
9763                                bringDownServiceLocked(sr, true);
9764                            }
9765                        }
9766                    }
9767                }
9768            }
9769
9770            if (!allowRestart) {
9771                app.services.clear();
9772            }
9773        }
9774
9775        // Make sure we have no more records on the stopping list.
9776        int i = mStoppingServices.size();
9777        while (i > 0) {
9778            i--;
9779            ServiceRecord sr = mStoppingServices.get(i);
9780            if (sr.app == app) {
9781                mStoppingServices.remove(i);
9782            }
9783        }
9784
9785        app.executingServices.clear();
9786    }
9787
9788    private final void removeDyingProviderLocked(ProcessRecord proc,
9789            ContentProviderRecord cpr) {
9790        synchronized (cpr) {
9791            cpr.launchingApp = null;
9792            cpr.notifyAll();
9793        }
9794
9795        mProvidersByClass.remove(cpr.info.name);
9796        String names[] = cpr.info.authority.split(";");
9797        for (int j = 0; j < names.length; j++) {
9798            mProvidersByName.remove(names[j]);
9799        }
9800
9801        Iterator<ProcessRecord> cit = cpr.clients.iterator();
9802        while (cit.hasNext()) {
9803            ProcessRecord capp = cit.next();
9804            if (!capp.persistent && capp.thread != null
9805                    && capp.pid != 0
9806                    && capp.pid != MY_PID) {
9807                Log.i(TAG, "Killing app " + capp.processName
9808                        + " (pid " + capp.pid
9809                        + ") because provider " + cpr.info.name
9810                        + " is in dying process " + proc.processName);
9811                Process.killProcess(capp.pid);
9812            }
9813        }
9814
9815        mLaunchingProviders.remove(cpr);
9816    }
9817
9818    /**
9819     * Main code for cleaning up a process when it has gone away.  This is
9820     * called both as a result of the process dying, or directly when stopping
9821     * a process when running in single process mode.
9822     */
9823    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
9824            boolean restarting, int index) {
9825        if (index >= 0) {
9826            mLRUProcesses.remove(index);
9827        }
9828
9829        // Dismiss any open dialogs.
9830        if (app.crashDialog != null) {
9831            app.crashDialog.dismiss();
9832            app.crashDialog = null;
9833        }
9834        if (app.anrDialog != null) {
9835            app.anrDialog.dismiss();
9836            app.anrDialog = null;
9837        }
9838        if (app.waitDialog != null) {
9839            app.waitDialog.dismiss();
9840            app.waitDialog = null;
9841        }
9842
9843        app.crashing = false;
9844        app.notResponding = false;
9845
9846        app.resetPackageList();
9847        app.thread = null;
9848        app.forcingToForeground = null;
9849        app.foregroundServices = false;
9850
9851        killServicesLocked(app, true);
9852
9853        boolean restart = false;
9854
9855        int NL = mLaunchingProviders.size();
9856
9857        // Remove published content providers.
9858        if (!app.pubProviders.isEmpty()) {
9859            Iterator it = app.pubProviders.values().iterator();
9860            while (it.hasNext()) {
9861                ContentProviderRecord cpr = (ContentProviderRecord)it.next();
9862                cpr.provider = null;
9863                cpr.app = null;
9864
9865                // See if someone is waiting for this provider...  in which
9866                // case we don't remove it, but just let it restart.
9867                int i = 0;
9868                if (!app.bad) {
9869                    for (; i<NL; i++) {
9870                        if (mLaunchingProviders.get(i) == cpr) {
9871                            restart = true;
9872                            break;
9873                        }
9874                    }
9875                } else {
9876                    i = NL;
9877                }
9878
9879                if (i >= NL) {
9880                    removeDyingProviderLocked(app, cpr);
9881                    NL = mLaunchingProviders.size();
9882                }
9883            }
9884            app.pubProviders.clear();
9885        }
9886
9887        // Look through the content providers we are waiting to have launched,
9888        // and if any run in this process then either schedule a restart of
9889        // the process or kill the client waiting for it if this process has
9890        // gone bad.
9891        for (int i=0; i<NL; i++) {
9892            ContentProviderRecord cpr = (ContentProviderRecord)
9893                    mLaunchingProviders.get(i);
9894            if (cpr.launchingApp == app) {
9895                if (!app.bad) {
9896                    restart = true;
9897                } else {
9898                    removeDyingProviderLocked(app, cpr);
9899                    NL = mLaunchingProviders.size();
9900                }
9901            }
9902        }
9903
9904        // Unregister from connected content providers.
9905        if (!app.conProviders.isEmpty()) {
9906            Iterator it = app.conProviders.iterator();
9907            while (it.hasNext()) {
9908                ContentProviderRecord cpr = (ContentProviderRecord)it.next();
9909                cpr.clients.remove(app);
9910            }
9911            app.conProviders.clear();
9912        }
9913
9914        // At this point there may be remaining entries in mLaunchingProviders
9915        // where we were the only one waiting, so they are no longer of use.
9916        // Look for these and clean up if found.
9917        // XXX Commented out for now.  Trying to figure out a way to reproduce
9918        // the actual situation to identify what is actually going on.
9919        if (false) {
9920            for (int i=0; i<NL; i++) {
9921                ContentProviderRecord cpr = (ContentProviderRecord)
9922                        mLaunchingProviders.get(i);
9923                if (cpr.clients.size() <= 0 && cpr.externals <= 0) {
9924                    synchronized (cpr) {
9925                        cpr.launchingApp = null;
9926                        cpr.notifyAll();
9927                    }
9928                }
9929            }
9930        }
9931
9932        skipCurrentReceiverLocked(app);
9933
9934        // Unregister any receivers.
9935        if (app.receivers.size() > 0) {
9936            Iterator<ReceiverList> it = app.receivers.iterator();
9937            while (it.hasNext()) {
9938                removeReceiverLocked(it.next());
9939            }
9940            app.receivers.clear();
9941        }
9942
9943        // If the app is undergoing backup, tell the backup manager about it
9944        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
9945            if (DEBUG_BACKUP) Log.d(TAG, "App " + mBackupTarget.appInfo + " died during backup");
9946            try {
9947                IBackupManager bm = IBackupManager.Stub.asInterface(
9948                        ServiceManager.getService(Context.BACKUP_SERVICE));
9949                bm.agentDisconnected(app.info.packageName);
9950            } catch (RemoteException e) {
9951                // can't happen; backup manager is local
9952            }
9953        }
9954
9955        // If the caller is restarting this app, then leave it in its
9956        // current lists and let the caller take care of it.
9957        if (restarting) {
9958            return;
9959        }
9960
9961        if (!app.persistent) {
9962            if (DEBUG_PROCESSES) Log.v(TAG,
9963                    "Removing non-persistent process during cleanup: " + app);
9964            mProcessNames.remove(app.processName, app.info.uid);
9965        } else if (!app.removed) {
9966            // This app is persistent, so we need to keep its record around.
9967            // If it is not already on the pending app list, add it there
9968            // and start a new process for it.
9969            app.thread = null;
9970            app.forcingToForeground = null;
9971            app.foregroundServices = false;
9972            if (mPersistentStartingProcesses.indexOf(app) < 0) {
9973                mPersistentStartingProcesses.add(app);
9974                restart = true;
9975            }
9976        }
9977        mProcessesOnHold.remove(app);
9978
9979        if (app == mHomeProcess) {
9980            mHomeProcess = null;
9981        }
9982
9983        if (restart) {
9984            // We have components that still need to be running in the
9985            // process, so re-launch it.
9986            mProcessNames.put(app.processName, app.info.uid, app);
9987            startProcessLocked(app, "restart", app.processName);
9988        } else if (app.pid > 0 && app.pid != MY_PID) {
9989            // Goodbye!
9990            synchronized (mPidsSelfLocked) {
9991                mPidsSelfLocked.remove(app.pid);
9992                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
9993            }
9994            app.setPid(0);
9995        }
9996    }
9997
9998    // =========================================================
9999    // SERVICES
10000    // =========================================================
10001
10002    ActivityManager.RunningServiceInfo makeRunningServiceInfoLocked(ServiceRecord r) {
10003        ActivityManager.RunningServiceInfo info =
10004            new ActivityManager.RunningServiceInfo();
10005        info.service = r.name;
10006        if (r.app != null) {
10007            info.pid = r.app.pid;
10008        }
10009        info.uid = r.appInfo.uid;
10010        info.process = r.processName;
10011        info.foreground = r.isForeground;
10012        info.activeSince = r.createTime;
10013        info.started = r.startRequested;
10014        info.clientCount = r.connections.size();
10015        info.crashCount = r.crashCount;
10016        info.lastActivityTime = r.lastActivity;
10017        if (r.isForeground) {
10018            info.flags |= ActivityManager.RunningServiceInfo.FLAG_FOREGROUND;
10019        }
10020        if (r.startRequested) {
10021            info.flags |= ActivityManager.RunningServiceInfo.FLAG_STARTED;
10022        }
10023        if (r.app != null && r.app.pid == Process.myPid()) {
10024            info.flags |= ActivityManager.RunningServiceInfo.FLAG_SYSTEM_PROCESS;
10025        }
10026        if (r.app != null && r.app.persistent) {
10027            info.flags |= ActivityManager.RunningServiceInfo.FLAG_PERSISTENT_PROCESS;
10028        }
10029        for (ConnectionRecord conn : r.connections.values()) {
10030            if (conn.clientLabel != 0) {
10031                info.clientPackage = conn.binding.client.info.packageName;
10032                info.clientLabel = conn.clientLabel;
10033                break;
10034            }
10035        }
10036        return info;
10037    }
10038
10039    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
10040            int flags) {
10041        synchronized (this) {
10042            ArrayList<ActivityManager.RunningServiceInfo> res
10043                    = new ArrayList<ActivityManager.RunningServiceInfo>();
10044
10045            if (mServices.size() > 0) {
10046                Iterator<ServiceRecord> it = mServices.values().iterator();
10047                while (it.hasNext() && res.size() < maxNum) {
10048                    res.add(makeRunningServiceInfoLocked(it.next()));
10049                }
10050            }
10051
10052            for (int i=0; i<mRestartingServices.size() && res.size() < maxNum; i++) {
10053                ServiceRecord r = mRestartingServices.get(i);
10054                ActivityManager.RunningServiceInfo info =
10055                        makeRunningServiceInfoLocked(r);
10056                info.restarting = r.nextRestartTime;
10057                res.add(info);
10058            }
10059
10060            return res;
10061        }
10062    }
10063
10064    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
10065        synchronized (this) {
10066            ServiceRecord r = mServices.get(name);
10067            if (r != null) {
10068                for (ConnectionRecord conn : r.connections.values()) {
10069                    if (conn.clientIntent != null) {
10070                        return conn.clientIntent;
10071                    }
10072                }
10073            }
10074        }
10075        return null;
10076    }
10077
10078    private final ServiceRecord findServiceLocked(ComponentName name,
10079            IBinder token) {
10080        ServiceRecord r = mServices.get(name);
10081        return r == token ? r : null;
10082    }
10083
10084    private final class ServiceLookupResult {
10085        final ServiceRecord record;
10086        final String permission;
10087
10088        ServiceLookupResult(ServiceRecord _record, String _permission) {
10089            record = _record;
10090            permission = _permission;
10091        }
10092    };
10093
10094    private ServiceLookupResult findServiceLocked(Intent service,
10095            String resolvedType) {
10096        ServiceRecord r = null;
10097        if (service.getComponent() != null) {
10098            r = mServices.get(service.getComponent());
10099        }
10100        if (r == null) {
10101            Intent.FilterComparison filter = new Intent.FilterComparison(service);
10102            r = mServicesByIntent.get(filter);
10103        }
10104
10105        if (r == null) {
10106            try {
10107                ResolveInfo rInfo =
10108                    ActivityThread.getPackageManager().resolveService(
10109                            service, resolvedType, 0);
10110                ServiceInfo sInfo =
10111                    rInfo != null ? rInfo.serviceInfo : null;
10112                if (sInfo == null) {
10113                    return null;
10114                }
10115
10116                ComponentName name = new ComponentName(
10117                        sInfo.applicationInfo.packageName, sInfo.name);
10118                r = mServices.get(name);
10119            } catch (RemoteException ex) {
10120                // pm is in same process, this will never happen.
10121            }
10122        }
10123        if (r != null) {
10124            int callingPid = Binder.getCallingPid();
10125            int callingUid = Binder.getCallingUid();
10126            if (checkComponentPermission(r.permission,
10127                    callingPid, callingUid, r.exported ? -1 : r.appInfo.uid)
10128                    != PackageManager.PERMISSION_GRANTED) {
10129                Log.w(TAG, "Permission Denial: Accessing service " + r.name
10130                        + " from pid=" + callingPid
10131                        + ", uid=" + callingUid
10132                        + " requires " + r.permission);
10133                return new ServiceLookupResult(null, r.permission);
10134            }
10135            return new ServiceLookupResult(r, null);
10136        }
10137        return null;
10138    }
10139
10140    private class ServiceRestarter implements Runnable {
10141        private ServiceRecord mService;
10142
10143        void setService(ServiceRecord service) {
10144            mService = service;
10145        }
10146
10147        public void run() {
10148            synchronized(ActivityManagerService.this) {
10149                performServiceRestartLocked(mService);
10150            }
10151        }
10152    }
10153
10154    private ServiceLookupResult retrieveServiceLocked(Intent service,
10155            String resolvedType, int callingPid, int callingUid) {
10156        ServiceRecord r = null;
10157        if (service.getComponent() != null) {
10158            r = mServices.get(service.getComponent());
10159        }
10160        Intent.FilterComparison filter = new Intent.FilterComparison(service);
10161        r = mServicesByIntent.get(filter);
10162        if (r == null) {
10163            try {
10164                ResolveInfo rInfo =
10165                    ActivityThread.getPackageManager().resolveService(
10166                            service, resolvedType, STOCK_PM_FLAGS);
10167                ServiceInfo sInfo =
10168                    rInfo != null ? rInfo.serviceInfo : null;
10169                if (sInfo == null) {
10170                    Log.w(TAG, "Unable to start service " + service +
10171                          ": not found");
10172                    return null;
10173                }
10174
10175                ComponentName name = new ComponentName(
10176                        sInfo.applicationInfo.packageName, sInfo.name);
10177                r = mServices.get(name);
10178                if (r == null) {
10179                    filter = new Intent.FilterComparison(service.cloneFilter());
10180                    ServiceRestarter res = new ServiceRestarter();
10181                    BatteryStatsImpl.Uid.Pkg.Serv ss = null;
10182                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10183                    synchronized (stats) {
10184                        ss = stats.getServiceStatsLocked(
10185                                sInfo.applicationInfo.uid, sInfo.packageName,
10186                                sInfo.name);
10187                    }
10188                    r = new ServiceRecord(ss, name, filter, sInfo, res);
10189                    res.setService(r);
10190                    mServices.put(name, r);
10191                    mServicesByIntent.put(filter, r);
10192
10193                    // Make sure this component isn't in the pending list.
10194                    int N = mPendingServices.size();
10195                    for (int i=0; i<N; i++) {
10196                        ServiceRecord pr = mPendingServices.get(i);
10197                        if (pr.name.equals(name)) {
10198                            mPendingServices.remove(i);
10199                            i--;
10200                            N--;
10201                        }
10202                    }
10203                }
10204            } catch (RemoteException ex) {
10205                // pm is in same process, this will never happen.
10206            }
10207        }
10208        if (r != null) {
10209            if (checkComponentPermission(r.permission,
10210                    callingPid, callingUid, r.exported ? -1 : r.appInfo.uid)
10211                    != PackageManager.PERMISSION_GRANTED) {
10212                Log.w(TAG, "Permission Denial: Accessing service " + r.name
10213                        + " from pid=" + Binder.getCallingPid()
10214                        + ", uid=" + Binder.getCallingUid()
10215                        + " requires " + r.permission);
10216                return new ServiceLookupResult(null, r.permission);
10217            }
10218            return new ServiceLookupResult(r, null);
10219        }
10220        return null;
10221    }
10222
10223    private final void bumpServiceExecutingLocked(ServiceRecord r) {
10224        long now = SystemClock.uptimeMillis();
10225        if (r.executeNesting == 0 && r.app != null) {
10226            if (r.app.executingServices.size() == 0) {
10227                Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
10228                msg.obj = r.app;
10229                mHandler.sendMessageAtTime(msg, now+SERVICE_TIMEOUT);
10230            }
10231            r.app.executingServices.add(r);
10232        }
10233        r.executeNesting++;
10234        r.executingStart = now;
10235    }
10236
10237    private final void sendServiceArgsLocked(ServiceRecord r,
10238            boolean oomAdjusted) {
10239        final int N = r.pendingStarts.size();
10240        if (N == 0) {
10241            return;
10242        }
10243
10244        int i = 0;
10245        while (i < N) {
10246            try {
10247                ServiceRecord.StartItem si = r.pendingStarts.get(i);
10248                if (DEBUG_SERVICE) Log.v(TAG, "Sending arguments to service: "
10249                        + r.name + " " + r.intent + " args=" + si.intent);
10250                if (si.intent == null && N > 1) {
10251                    // If somehow we got a dummy start at the front, then
10252                    // just drop it here.
10253                    i++;
10254                    continue;
10255                }
10256                bumpServiceExecutingLocked(r);
10257                if (!oomAdjusted) {
10258                    oomAdjusted = true;
10259                    updateOomAdjLocked(r.app);
10260                }
10261                int flags = 0;
10262                if (si.deliveryCount > 0) {
10263                    flags |= Service.START_FLAG_RETRY;
10264                }
10265                if (si.doneExecutingCount > 0) {
10266                    flags |= Service.START_FLAG_REDELIVERY;
10267                }
10268                r.app.thread.scheduleServiceArgs(r, si.id, flags, si.intent);
10269                si.deliveredTime = SystemClock.uptimeMillis();
10270                r.deliveredStarts.add(si);
10271                si.deliveryCount++;
10272                i++;
10273            } catch (RemoteException e) {
10274                // Remote process gone...  we'll let the normal cleanup take
10275                // care of this.
10276                break;
10277            } catch (Exception e) {
10278                Log.w(TAG, "Unexpected exception", e);
10279                break;
10280            }
10281        }
10282        if (i == N) {
10283            r.pendingStarts.clear();
10284        } else {
10285            while (i > 0) {
10286                i--;
10287                r.pendingStarts.remove(i);
10288            }
10289        }
10290    }
10291
10292    private final boolean requestServiceBindingLocked(ServiceRecord r,
10293            IntentBindRecord i, boolean rebind) {
10294        if (r.app == null || r.app.thread == null) {
10295            // If service is not currently running, can't yet bind.
10296            return false;
10297        }
10298        if ((!i.requested || rebind) && i.apps.size() > 0) {
10299            try {
10300                bumpServiceExecutingLocked(r);
10301                if (DEBUG_SERVICE) Log.v(TAG, "Connecting binding " + i
10302                        + ": shouldUnbind=" + i.hasBound);
10303                r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind);
10304                if (!rebind) {
10305                    i.requested = true;
10306                }
10307                i.hasBound = true;
10308                i.doRebind = false;
10309            } catch (RemoteException e) {
10310                return false;
10311            }
10312        }
10313        return true;
10314    }
10315
10316    private final void requestServiceBindingsLocked(ServiceRecord r) {
10317        Iterator<IntentBindRecord> bindings = r.bindings.values().iterator();
10318        while (bindings.hasNext()) {
10319            IntentBindRecord i = bindings.next();
10320            if (!requestServiceBindingLocked(r, i, false)) {
10321                break;
10322            }
10323        }
10324    }
10325
10326    private final void realStartServiceLocked(ServiceRecord r,
10327            ProcessRecord app) throws RemoteException {
10328        if (app.thread == null) {
10329            throw new RemoteException();
10330        }
10331
10332        r.app = app;
10333        r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
10334
10335        app.services.add(r);
10336        bumpServiceExecutingLocked(r);
10337        updateLRUListLocked(app, true);
10338
10339        boolean created = false;
10340        try {
10341            if (DEBUG_SERVICE) Log.v(TAG, "Scheduling start service: "
10342                    + r.name + " " + r.intent);
10343            EventLog.writeEvent(LOG_AM_CREATE_SERVICE,
10344                    System.identityHashCode(r), r.shortName,
10345                    r.intent.getIntent().toString(), r.app.pid);
10346            synchronized (r.stats.getBatteryStats()) {
10347                r.stats.startLaunchedLocked();
10348            }
10349            ensurePackageDexOpt(r.serviceInfo.packageName);
10350            app.thread.scheduleCreateService(r, r.serviceInfo);
10351            r.postNotification();
10352            created = true;
10353        } finally {
10354            if (!created) {
10355                app.services.remove(r);
10356                scheduleServiceRestartLocked(r, false);
10357            }
10358        }
10359
10360        requestServiceBindingsLocked(r);
10361
10362        // If the service is in the started state, and there are no
10363        // pending arguments, then fake up one so its onStartCommand() will
10364        // be called.
10365        if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
10366            r.lastStartId++;
10367            if (r.lastStartId < 1) {
10368                r.lastStartId = 1;
10369            }
10370            r.pendingStarts.add(new ServiceRecord.StartItem(r.lastStartId, null));
10371        }
10372
10373        sendServiceArgsLocked(r, true);
10374    }
10375
10376    private final boolean scheduleServiceRestartLocked(ServiceRecord r,
10377            boolean allowCancel) {
10378        boolean canceled = false;
10379
10380        final long now = SystemClock.uptimeMillis();
10381        long minDuration = SERVICE_RESTART_DURATION;
10382        long resetTime = SERVICE_RESET_RUN_DURATION;
10383
10384        // Any delivered but not yet finished starts should be put back
10385        // on the pending list.
10386        final int N = r.deliveredStarts.size();
10387        if (N > 0) {
10388            for (int i=N-1; i>=0; i--) {
10389                ServiceRecord.StartItem si = r.deliveredStarts.get(i);
10390                if (si.intent == null) {
10391                    // We'll generate this again if needed.
10392                } else if (!allowCancel || (si.deliveryCount < ServiceRecord.MAX_DELIVERY_COUNT
10393                        && si.doneExecutingCount < ServiceRecord.MAX_DONE_EXECUTING_COUNT)) {
10394                    r.pendingStarts.add(0, si);
10395                    long dur = SystemClock.uptimeMillis() - si.deliveredTime;
10396                    dur *= 2;
10397                    if (minDuration < dur) minDuration = dur;
10398                    if (resetTime < dur) resetTime = dur;
10399                } else {
10400                    Log.w(TAG, "Canceling start item " + si.intent + " in service "
10401                            + r.name);
10402                    canceled = true;
10403                }
10404            }
10405            r.deliveredStarts.clear();
10406        }
10407
10408        r.totalRestartCount++;
10409        if (r.restartDelay == 0) {
10410            r.restartCount++;
10411            r.restartDelay = minDuration;
10412        } else {
10413            // If it has been a "reasonably long time" since the service
10414            // was started, then reset our restart duration back to
10415            // the beginning, so we don't infinitely increase the duration
10416            // on a service that just occasionally gets killed (which is
10417            // a normal case, due to process being killed to reclaim memory).
10418            if (now > (r.restartTime+resetTime)) {
10419                r.restartCount = 1;
10420                r.restartDelay = minDuration;
10421            } else {
10422                r.restartDelay *= SERVICE_RESTART_DURATION_FACTOR;
10423                if (r.restartDelay < minDuration) {
10424                    r.restartDelay = minDuration;
10425                }
10426            }
10427        }
10428
10429        r.nextRestartTime = now + r.restartDelay;
10430
10431        // Make sure that we don't end up restarting a bunch of services
10432        // all at the same time.
10433        boolean repeat;
10434        do {
10435            repeat = false;
10436            for (int i=mRestartingServices.size()-1; i>=0; i--) {
10437                ServiceRecord r2 = mRestartingServices.get(i);
10438                if (r2 != r && r.nextRestartTime
10439                        >= (r2.nextRestartTime-SERVICE_MIN_RESTART_TIME_BETWEEN)
10440                        && r.nextRestartTime
10441                        < (r2.nextRestartTime+SERVICE_MIN_RESTART_TIME_BETWEEN)) {
10442                    r.nextRestartTime = r2.nextRestartTime + SERVICE_MIN_RESTART_TIME_BETWEEN;
10443                    r.restartDelay = r.nextRestartTime - now;
10444                    repeat = true;
10445                    break;
10446                }
10447            }
10448        } while (repeat);
10449
10450        if (!mRestartingServices.contains(r)) {
10451            mRestartingServices.add(r);
10452        }
10453
10454        r.cancelNotification();
10455
10456        mHandler.removeCallbacks(r.restarter);
10457        mHandler.postAtTime(r.restarter, r.nextRestartTime);
10458        r.nextRestartTime = SystemClock.uptimeMillis() + r.restartDelay;
10459        Log.w(TAG, "Scheduling restart of crashed service "
10460                + r.shortName + " in " + r.restartDelay + "ms");
10461        EventLog.writeEvent(LOG_AM_SCHEDULE_SERVICE_RESTART,
10462                r.shortName, r.restartDelay);
10463
10464        Message msg = Message.obtain();
10465        msg.what = SERVICE_ERROR_MSG;
10466        msg.obj = r;
10467        mHandler.sendMessage(msg);
10468
10469        return canceled;
10470    }
10471
10472    final void performServiceRestartLocked(ServiceRecord r) {
10473        if (!mRestartingServices.contains(r)) {
10474            return;
10475        }
10476        bringUpServiceLocked(r, r.intent.getIntent().getFlags(), true);
10477    }
10478
10479    private final boolean unscheduleServiceRestartLocked(ServiceRecord r) {
10480        if (r.restartDelay == 0) {
10481            return false;
10482        }
10483        r.resetRestartCounter();
10484        mRestartingServices.remove(r);
10485        mHandler.removeCallbacks(r.restarter);
10486        return true;
10487    }
10488
10489    private final boolean bringUpServiceLocked(ServiceRecord r,
10490            int intentFlags, boolean whileRestarting) {
10491        //Log.i(TAG, "Bring up service:");
10492        //r.dump("  ");
10493
10494        if (r.app != null) {
10495            sendServiceArgsLocked(r, false);
10496            return true;
10497        }
10498
10499        if (!whileRestarting && r.restartDelay > 0) {
10500            // If waiting for a restart, then do nothing.
10501            return true;
10502        }
10503
10504        if (DEBUG_SERVICE) Log.v(TAG, "Bringing up service " + r.name
10505                + " " + r.intent);
10506
10507        // We are now bringing the service up, so no longer in the
10508        // restarting state.
10509        mRestartingServices.remove(r);
10510
10511        final String appName = r.processName;
10512        ProcessRecord app = getProcessRecordLocked(appName, r.appInfo.uid);
10513        if (app != null && app.thread != null) {
10514            try {
10515                realStartServiceLocked(r, app);
10516                return true;
10517            } catch (RemoteException e) {
10518                Log.w(TAG, "Exception when starting service " + r.shortName, e);
10519            }
10520
10521            // If a dead object exception was thrown -- fall through to
10522            // restart the application.
10523        }
10524
10525        if (!mPendingServices.contains(r)) {
10526            // Not running -- get it started, and enqueue this service record
10527            // to be executed when the app comes up.
10528            if (startProcessLocked(appName, r.appInfo, true, intentFlags,
10529                    "service", r.name, false) == null) {
10530                Log.w(TAG, "Unable to launch app "
10531                        + r.appInfo.packageName + "/"
10532                        + r.appInfo.uid + " for service "
10533                        + r.intent.getIntent() + ": process is bad");
10534                bringDownServiceLocked(r, true);
10535                return false;
10536            }
10537            mPendingServices.add(r);
10538        }
10539        return true;
10540    }
10541
10542    private final void bringDownServiceLocked(ServiceRecord r, boolean force) {
10543        //Log.i(TAG, "Bring down service:");
10544        //r.dump("  ");
10545
10546        // Does it still need to run?
10547        if (!force && r.startRequested) {
10548            return;
10549        }
10550        if (r.connections.size() > 0) {
10551            if (!force) {
10552                // XXX should probably keep a count of the number of auto-create
10553                // connections directly in the service.
10554                Iterator<ConnectionRecord> it = r.connections.values().iterator();
10555                while (it.hasNext()) {
10556                    ConnectionRecord cr = it.next();
10557                    if ((cr.flags&Context.BIND_AUTO_CREATE) != 0) {
10558                        return;
10559                    }
10560                }
10561            }
10562
10563            // Report to all of the connections that the service is no longer
10564            // available.
10565            Iterator<ConnectionRecord> it = r.connections.values().iterator();
10566            while (it.hasNext()) {
10567                ConnectionRecord c = it.next();
10568                try {
10569                    // todo: shouldn't be a synchronous call!
10570                    c.conn.connected(r.name, null);
10571                } catch (Exception e) {
10572                    Log.w(TAG, "Failure disconnecting service " + r.name +
10573                          " to connection " + c.conn.asBinder() +
10574                          " (in " + c.binding.client.processName + ")", e);
10575                }
10576            }
10577        }
10578
10579        // Tell the service that it has been unbound.
10580        if (r.bindings.size() > 0 && r.app != null && r.app.thread != null) {
10581            Iterator<IntentBindRecord> it = r.bindings.values().iterator();
10582            while (it.hasNext()) {
10583                IntentBindRecord ibr = it.next();
10584                if (DEBUG_SERVICE) Log.v(TAG, "Bringing down binding " + ibr
10585                        + ": hasBound=" + ibr.hasBound);
10586                if (r.app != null && r.app.thread != null && ibr.hasBound) {
10587                    try {
10588                        bumpServiceExecutingLocked(r);
10589                        updateOomAdjLocked(r.app);
10590                        ibr.hasBound = false;
10591                        r.app.thread.scheduleUnbindService(r,
10592                                ibr.intent.getIntent());
10593                    } catch (Exception e) {
10594                        Log.w(TAG, "Exception when unbinding service "
10595                                + r.shortName, e);
10596                        serviceDoneExecutingLocked(r, true);
10597                    }
10598                }
10599            }
10600        }
10601
10602        if (DEBUG_SERVICE) Log.v(TAG, "Bringing down service " + r.name
10603                 + " " + r.intent);
10604        EventLog.writeEvent(LOG_AM_DESTROY_SERVICE,
10605                System.identityHashCode(r), r.shortName,
10606                (r.app != null) ? r.app.pid : -1);
10607
10608        mServices.remove(r.name);
10609        mServicesByIntent.remove(r.intent);
10610        if (localLOGV) Log.v(TAG, "BRING DOWN SERVICE: " + r.shortName);
10611        r.totalRestartCount = 0;
10612        unscheduleServiceRestartLocked(r);
10613
10614        // Also make sure it is not on the pending list.
10615        int N = mPendingServices.size();
10616        for (int i=0; i<N; i++) {
10617            if (mPendingServices.get(i) == r) {
10618                mPendingServices.remove(i);
10619                if (DEBUG_SERVICE) Log.v(
10620                    TAG, "Removed pending service: " + r.shortName);
10621                i--;
10622                N--;
10623            }
10624        }
10625
10626        r.cancelNotification();
10627        r.isForeground = false;
10628        r.foregroundId = 0;
10629        r.foregroundNoti = null;
10630
10631        // Clear start entries.
10632        r.deliveredStarts.clear();
10633        r.pendingStarts.clear();
10634
10635        if (r.app != null) {
10636            synchronized (r.stats.getBatteryStats()) {
10637                r.stats.stopLaunchedLocked();
10638            }
10639            r.app.services.remove(r);
10640            if (r.app.thread != null) {
10641                try {
10642                    if (DEBUG_SERVICE) Log.v(TAG,
10643                            "Stopping service: " + r.shortName);
10644                    bumpServiceExecutingLocked(r);
10645                    mStoppingServices.add(r);
10646                    updateOomAdjLocked(r.app);
10647                    r.app.thread.scheduleStopService(r);
10648                } catch (Exception e) {
10649                    Log.w(TAG, "Exception when stopping service "
10650                            + r.shortName, e);
10651                    serviceDoneExecutingLocked(r, true);
10652                }
10653                updateServiceForegroundLocked(r.app, false);
10654            } else {
10655                if (DEBUG_SERVICE) Log.v(
10656                    TAG, "Removed service that has no process: " + r.shortName);
10657            }
10658        } else {
10659            if (DEBUG_SERVICE) Log.v(
10660                TAG, "Removed service that is not running: " + r.shortName);
10661        }
10662    }
10663
10664    ComponentName startServiceLocked(IApplicationThread caller,
10665            Intent service, String resolvedType,
10666            int callingPid, int callingUid) {
10667        synchronized(this) {
10668            if (DEBUG_SERVICE) Log.v(TAG, "startService: " + service
10669                    + " type=" + resolvedType + " args=" + service.getExtras());
10670
10671            if (caller != null) {
10672                final ProcessRecord callerApp = getRecordForAppLocked(caller);
10673                if (callerApp == null) {
10674                    throw new SecurityException(
10675                            "Unable to find app for caller " + caller
10676                            + " (pid=" + Binder.getCallingPid()
10677                            + ") when starting service " + service);
10678                }
10679            }
10680
10681            ServiceLookupResult res =
10682                retrieveServiceLocked(service, resolvedType,
10683                        callingPid, callingUid);
10684            if (res == null) {
10685                return null;
10686            }
10687            if (res.record == null) {
10688                return new ComponentName("!", res.permission != null
10689                        ? res.permission : "private to package");
10690            }
10691            ServiceRecord r = res.record;
10692            if (unscheduleServiceRestartLocked(r)) {
10693                if (DEBUG_SERVICE) Log.v(TAG, "START SERVICE WHILE RESTART PENDING: "
10694                        + r.shortName);
10695            }
10696            r.startRequested = true;
10697            r.callStart = false;
10698            r.lastStartId++;
10699            if (r.lastStartId < 1) {
10700                r.lastStartId = 1;
10701            }
10702            r.pendingStarts.add(new ServiceRecord.StartItem(r.lastStartId, service));
10703            r.lastActivity = SystemClock.uptimeMillis();
10704            synchronized (r.stats.getBatteryStats()) {
10705                r.stats.startRunningLocked();
10706            }
10707            if (!bringUpServiceLocked(r, service.getFlags(), false)) {
10708                return new ComponentName("!", "Service process is bad");
10709            }
10710            return r.name;
10711        }
10712    }
10713
10714    public ComponentName startService(IApplicationThread caller, Intent service,
10715            String resolvedType) {
10716        // Refuse possible leaked file descriptors
10717        if (service != null && service.hasFileDescriptors() == true) {
10718            throw new IllegalArgumentException("File descriptors passed in Intent");
10719        }
10720
10721        synchronized(this) {
10722            final int callingPid = Binder.getCallingPid();
10723            final int callingUid = Binder.getCallingUid();
10724            final long origId = Binder.clearCallingIdentity();
10725            ComponentName res = startServiceLocked(caller, service,
10726                    resolvedType, callingPid, callingUid);
10727            Binder.restoreCallingIdentity(origId);
10728            return res;
10729        }
10730    }
10731
10732    ComponentName startServiceInPackage(int uid,
10733            Intent service, String resolvedType) {
10734        synchronized(this) {
10735            final long origId = Binder.clearCallingIdentity();
10736            ComponentName res = startServiceLocked(null, service,
10737                    resolvedType, -1, uid);
10738            Binder.restoreCallingIdentity(origId);
10739            return res;
10740        }
10741    }
10742
10743    public int stopService(IApplicationThread caller, Intent service,
10744            String resolvedType) {
10745        // Refuse possible leaked file descriptors
10746        if (service != null && service.hasFileDescriptors() == true) {
10747            throw new IllegalArgumentException("File descriptors passed in Intent");
10748        }
10749
10750        synchronized(this) {
10751            if (DEBUG_SERVICE) Log.v(TAG, "stopService: " + service
10752                    + " type=" + resolvedType);
10753
10754            final ProcessRecord callerApp = getRecordForAppLocked(caller);
10755            if (caller != null && callerApp == null) {
10756                throw new SecurityException(
10757                        "Unable to find app for caller " + caller
10758                        + " (pid=" + Binder.getCallingPid()
10759                        + ") when stopping service " + service);
10760            }
10761
10762            // If this service is active, make sure it is stopped.
10763            ServiceLookupResult r = findServiceLocked(service, resolvedType);
10764            if (r != null) {
10765                if (r.record != null) {
10766                    synchronized (r.record.stats.getBatteryStats()) {
10767                        r.record.stats.stopRunningLocked();
10768                    }
10769                    r.record.startRequested = false;
10770                    r.record.callStart = false;
10771                    final long origId = Binder.clearCallingIdentity();
10772                    bringDownServiceLocked(r.record, false);
10773                    Binder.restoreCallingIdentity(origId);
10774                    return 1;
10775                }
10776                return -1;
10777            }
10778        }
10779
10780        return 0;
10781    }
10782
10783    public IBinder peekService(Intent service, String resolvedType) {
10784        // Refuse possible leaked file descriptors
10785        if (service != null && service.hasFileDescriptors() == true) {
10786            throw new IllegalArgumentException("File descriptors passed in Intent");
10787        }
10788
10789        IBinder ret = null;
10790
10791        synchronized(this) {
10792            ServiceLookupResult r = findServiceLocked(service, resolvedType);
10793
10794            if (r != null) {
10795                // r.record is null if findServiceLocked() failed the caller permission check
10796                if (r.record == null) {
10797                    throw new SecurityException(
10798                            "Permission Denial: Accessing service " + r.record.name
10799                            + " from pid=" + Binder.getCallingPid()
10800                            + ", uid=" + Binder.getCallingUid()
10801                            + " requires " + r.permission);
10802                }
10803                IntentBindRecord ib = r.record.bindings.get(r.record.intent);
10804                if (ib != null) {
10805                    ret = ib.binder;
10806                }
10807            }
10808        }
10809
10810        return ret;
10811    }
10812
10813    public boolean stopServiceToken(ComponentName className, IBinder token,
10814            int startId) {
10815        synchronized(this) {
10816            if (DEBUG_SERVICE) Log.v(TAG, "stopServiceToken: " + className
10817                    + " " + token + " startId=" + startId);
10818            ServiceRecord r = findServiceLocked(className, token);
10819            if (r != null) {
10820                if (startId >= 0) {
10821                    // Asked to only stop if done with all work.  Note that
10822                    // to avoid leaks, we will take this as dropping all
10823                    // start items up to and including this one.
10824                    ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
10825                    if (si != null) {
10826                        while (r.deliveredStarts.size() > 0) {
10827                            if (r.deliveredStarts.remove(0) == si) {
10828                                break;
10829                            }
10830                        }
10831                    }
10832
10833                    if (r.lastStartId != startId) {
10834                        return false;
10835                    }
10836
10837                    if (r.deliveredStarts.size() > 0) {
10838                        Log.w(TAG, "stopServiceToken startId " + startId
10839                                + " is last, but have " + r.deliveredStarts.size()
10840                                + " remaining args");
10841                    }
10842                }
10843
10844                synchronized (r.stats.getBatteryStats()) {
10845                    r.stats.stopRunningLocked();
10846                    r.startRequested = false;
10847                    r.callStart = false;
10848                }
10849                final long origId = Binder.clearCallingIdentity();
10850                bringDownServiceLocked(r, false);
10851                Binder.restoreCallingIdentity(origId);
10852                return true;
10853            }
10854        }
10855        return false;
10856    }
10857
10858    public void setServiceForeground(ComponentName className, IBinder token,
10859            int id, Notification notification, boolean removeNotification) {
10860        final long origId = Binder.clearCallingIdentity();
10861        try {
10862        synchronized(this) {
10863            ServiceRecord r = findServiceLocked(className, token);
10864            if (r != null) {
10865                if (id != 0) {
10866                    if (notification == null) {
10867                        throw new IllegalArgumentException("null notification");
10868                    }
10869                    if (r.foregroundId != id) {
10870                        r.cancelNotification();
10871                        r.foregroundId = id;
10872                    }
10873                    notification.flags |= Notification.FLAG_FOREGROUND_SERVICE;
10874                    r.foregroundNoti = notification;
10875                    r.isForeground = true;
10876                    r.postNotification();
10877                    if (r.app != null) {
10878                        updateServiceForegroundLocked(r.app, true);
10879                    }
10880                } else {
10881                    if (r.isForeground) {
10882                        r.isForeground = false;
10883                        if (r.app != null) {
10884                            updateServiceForegroundLocked(r.app, true);
10885                        }
10886                    }
10887                    if (removeNotification) {
10888                        r.cancelNotification();
10889                        r.foregroundId = 0;
10890                        r.foregroundNoti = null;
10891                    }
10892                }
10893            }
10894        }
10895        } finally {
10896            Binder.restoreCallingIdentity(origId);
10897        }
10898    }
10899
10900    public void updateServiceForegroundLocked(ProcessRecord proc, boolean oomAdj) {
10901        boolean anyForeground = false;
10902        for (ServiceRecord sr : (HashSet<ServiceRecord>)proc.services) {
10903            if (sr.isForeground) {
10904                anyForeground = true;
10905                break;
10906            }
10907        }
10908        if (anyForeground != proc.foregroundServices) {
10909            proc.foregroundServices = anyForeground;
10910            if (oomAdj) {
10911                updateOomAdjLocked();
10912            }
10913        }
10914    }
10915
10916    public int bindService(IApplicationThread caller, IBinder token,
10917            Intent service, String resolvedType,
10918            IServiceConnection connection, int flags) {
10919        // Refuse possible leaked file descriptors
10920        if (service != null && service.hasFileDescriptors() == true) {
10921            throw new IllegalArgumentException("File descriptors passed in Intent");
10922        }
10923
10924        synchronized(this) {
10925            if (DEBUG_SERVICE) Log.v(TAG, "bindService: " + service
10926                    + " type=" + resolvedType + " conn=" + connection.asBinder()
10927                    + " flags=0x" + Integer.toHexString(flags));
10928            final ProcessRecord callerApp = getRecordForAppLocked(caller);
10929            if (callerApp == null) {
10930                throw new SecurityException(
10931                        "Unable to find app for caller " + caller
10932                        + " (pid=" + Binder.getCallingPid()
10933                        + ") when binding service " + service);
10934            }
10935
10936            HistoryRecord activity = null;
10937            if (token != null) {
10938                int aindex = indexOfTokenLocked(token);
10939                if (aindex < 0) {
10940                    Log.w(TAG, "Binding with unknown activity: " + token);
10941                    return 0;
10942                }
10943                activity = (HistoryRecord)mHistory.get(aindex);
10944            }
10945
10946            int clientLabel = 0;
10947            PendingIntent clientIntent = null;
10948
10949            if (callerApp.info.uid == Process.SYSTEM_UID) {
10950                // Hacky kind of thing -- allow system stuff to tell us
10951                // what they are, so we can report this elsewhere for
10952                // others to know why certain services are running.
10953                try {
10954                    clientIntent = (PendingIntent)service.getParcelableExtra(
10955                            Intent.EXTRA_CLIENT_INTENT);
10956                } catch (RuntimeException e) {
10957                }
10958                if (clientIntent != null) {
10959                    clientLabel = service.getIntExtra(Intent.EXTRA_CLIENT_LABEL, 0);
10960                    if (clientLabel != 0) {
10961                        // There are no useful extras in the intent, trash them.
10962                        // System code calling with this stuff just needs to know
10963                        // this will happen.
10964                        service = service.cloneFilter();
10965                    }
10966                }
10967            }
10968
10969            ServiceLookupResult res =
10970                retrieveServiceLocked(service, resolvedType,
10971                        Binder.getCallingPid(), Binder.getCallingUid());
10972            if (res == null) {
10973                return 0;
10974            }
10975            if (res.record == null) {
10976                return -1;
10977            }
10978            ServiceRecord s = res.record;
10979
10980            final long origId = Binder.clearCallingIdentity();
10981
10982            if (unscheduleServiceRestartLocked(s)) {
10983                if (DEBUG_SERVICE) Log.v(TAG, "BIND SERVICE WHILE RESTART PENDING: "
10984                        + s.shortName);
10985            }
10986
10987            AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
10988            ConnectionRecord c = new ConnectionRecord(b, activity,
10989                    connection, flags, clientLabel, clientIntent);
10990
10991            IBinder binder = connection.asBinder();
10992            s.connections.put(binder, c);
10993            b.connections.add(c);
10994            if (activity != null) {
10995                if (activity.connections == null) {
10996                    activity.connections = new HashSet<ConnectionRecord>();
10997                }
10998                activity.connections.add(c);
10999            }
11000            b.client.connections.add(c);
11001            mServiceConnections.put(binder, c);
11002
11003            if ((flags&Context.BIND_AUTO_CREATE) != 0) {
11004                s.lastActivity = SystemClock.uptimeMillis();
11005                if (!bringUpServiceLocked(s, service.getFlags(), false)) {
11006                    return 0;
11007                }
11008            }
11009
11010            if (s.app != null) {
11011                // This could have made the service more important.
11012                updateOomAdjLocked(s.app);
11013            }
11014
11015            if (DEBUG_SERVICE) Log.v(TAG, "Bind " + s + " with " + b
11016                    + ": received=" + b.intent.received
11017                    + " apps=" + b.intent.apps.size()
11018                    + " doRebind=" + b.intent.doRebind);
11019
11020            if (s.app != null && b.intent.received) {
11021                // Service is already running, so we can immediately
11022                // publish the connection.
11023                try {
11024                    c.conn.connected(s.name, b.intent.binder);
11025                } catch (Exception e) {
11026                    Log.w(TAG, "Failure sending service " + s.shortName
11027                            + " to connection " + c.conn.asBinder()
11028                            + " (in " + c.binding.client.processName + ")", e);
11029                }
11030
11031                // If this is the first app connected back to this binding,
11032                // and the service had previously asked to be told when
11033                // rebound, then do so.
11034                if (b.intent.apps.size() == 1 && b.intent.doRebind) {
11035                    requestServiceBindingLocked(s, b.intent, true);
11036                }
11037            } else if (!b.intent.requested) {
11038                requestServiceBindingLocked(s, b.intent, false);
11039            }
11040
11041            Binder.restoreCallingIdentity(origId);
11042        }
11043
11044        return 1;
11045    }
11046
11047    private void removeConnectionLocked(
11048        ConnectionRecord c, ProcessRecord skipApp, HistoryRecord skipAct) {
11049        IBinder binder = c.conn.asBinder();
11050        AppBindRecord b = c.binding;
11051        ServiceRecord s = b.service;
11052        s.connections.remove(binder);
11053        b.connections.remove(c);
11054        if (c.activity != null && c.activity != skipAct) {
11055            if (c.activity.connections != null) {
11056                c.activity.connections.remove(c);
11057            }
11058        }
11059        if (b.client != skipApp) {
11060            b.client.connections.remove(c);
11061        }
11062        mServiceConnections.remove(binder);
11063
11064        if (b.connections.size() == 0) {
11065            b.intent.apps.remove(b.client);
11066        }
11067
11068        if (DEBUG_SERVICE) Log.v(TAG, "Disconnecting binding " + b.intent
11069                + ": shouldUnbind=" + b.intent.hasBound);
11070        if (s.app != null && s.app.thread != null && b.intent.apps.size() == 0
11071                && b.intent.hasBound) {
11072            try {
11073                bumpServiceExecutingLocked(s);
11074                updateOomAdjLocked(s.app);
11075                b.intent.hasBound = false;
11076                // Assume the client doesn't want to know about a rebind;
11077                // we will deal with that later if it asks for one.
11078                b.intent.doRebind = false;
11079                s.app.thread.scheduleUnbindService(s, b.intent.intent.getIntent());
11080            } catch (Exception e) {
11081                Log.w(TAG, "Exception when unbinding service " + s.shortName, e);
11082                serviceDoneExecutingLocked(s, true);
11083            }
11084        }
11085
11086        if ((c.flags&Context.BIND_AUTO_CREATE) != 0) {
11087            bringDownServiceLocked(s, false);
11088        }
11089    }
11090
11091    public boolean unbindService(IServiceConnection connection) {
11092        synchronized (this) {
11093            IBinder binder = connection.asBinder();
11094            if (DEBUG_SERVICE) Log.v(TAG, "unbindService: conn=" + binder);
11095            ConnectionRecord r = mServiceConnections.get(binder);
11096            if (r == null) {
11097                Log.w(TAG, "Unbind failed: could not find connection for "
11098                      + connection.asBinder());
11099                return false;
11100            }
11101
11102            final long origId = Binder.clearCallingIdentity();
11103
11104            removeConnectionLocked(r, null, null);
11105
11106            if (r.binding.service.app != null) {
11107                // This could have made the service less important.
11108                updateOomAdjLocked(r.binding.service.app);
11109            }
11110
11111            Binder.restoreCallingIdentity(origId);
11112        }
11113
11114        return true;
11115    }
11116
11117    public void publishService(IBinder token, Intent intent, IBinder service) {
11118        // Refuse possible leaked file descriptors
11119        if (intent != null && intent.hasFileDescriptors() == true) {
11120            throw new IllegalArgumentException("File descriptors passed in Intent");
11121        }
11122
11123        synchronized(this) {
11124            if (!(token instanceof ServiceRecord)) {
11125                throw new IllegalArgumentException("Invalid service token");
11126            }
11127            ServiceRecord r = (ServiceRecord)token;
11128
11129            final long origId = Binder.clearCallingIdentity();
11130
11131            if (DEBUG_SERVICE) Log.v(TAG, "PUBLISHING SERVICE " + r.name
11132                    + " " + intent + ": " + service);
11133            if (r != null) {
11134                Intent.FilterComparison filter
11135                        = new Intent.FilterComparison(intent);
11136                IntentBindRecord b = r.bindings.get(filter);
11137                if (b != null && !b.received) {
11138                    b.binder = service;
11139                    b.requested = true;
11140                    b.received = true;
11141                    if (r.connections.size() > 0) {
11142                        Iterator<ConnectionRecord> it
11143                                = r.connections.values().iterator();
11144                        while (it.hasNext()) {
11145                            ConnectionRecord c = it.next();
11146                            if (!filter.equals(c.binding.intent.intent)) {
11147                                if (DEBUG_SERVICE) Log.v(
11148                                        TAG, "Not publishing to: " + c);
11149                                if (DEBUG_SERVICE) Log.v(
11150                                        TAG, "Bound intent: " + c.binding.intent.intent);
11151                                if (DEBUG_SERVICE) Log.v(
11152                                        TAG, "Published intent: " + intent);
11153                                continue;
11154                            }
11155                            if (DEBUG_SERVICE) Log.v(TAG, "Publishing to: " + c);
11156                            try {
11157                                c.conn.connected(r.name, service);
11158                            } catch (Exception e) {
11159                                Log.w(TAG, "Failure sending service " + r.name +
11160                                      " to connection " + c.conn.asBinder() +
11161                                      " (in " + c.binding.client.processName + ")", e);
11162                            }
11163                        }
11164                    }
11165                }
11166
11167                serviceDoneExecutingLocked(r, mStoppingServices.contains(r));
11168
11169                Binder.restoreCallingIdentity(origId);
11170            }
11171        }
11172    }
11173
11174    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
11175        // Refuse possible leaked file descriptors
11176        if (intent != null && intent.hasFileDescriptors() == true) {
11177            throw new IllegalArgumentException("File descriptors passed in Intent");
11178        }
11179
11180        synchronized(this) {
11181            if (!(token instanceof ServiceRecord)) {
11182                throw new IllegalArgumentException("Invalid service token");
11183            }
11184            ServiceRecord r = (ServiceRecord)token;
11185
11186            final long origId = Binder.clearCallingIdentity();
11187
11188            if (r != null) {
11189                Intent.FilterComparison filter
11190                        = new Intent.FilterComparison(intent);
11191                IntentBindRecord b = r.bindings.get(filter);
11192                if (DEBUG_SERVICE) Log.v(TAG, "unbindFinished in " + r
11193                        + " at " + b + ": apps="
11194                        + (b != null ? b.apps.size() : 0));
11195                if (b != null) {
11196                    if (b.apps.size() > 0) {
11197                        // Applications have already bound since the last
11198                        // unbind, so just rebind right here.
11199                        requestServiceBindingLocked(r, b, true);
11200                    } else {
11201                        // Note to tell the service the next time there is
11202                        // a new client.
11203                        b.doRebind = true;
11204                    }
11205                }
11206
11207                serviceDoneExecutingLocked(r, mStoppingServices.contains(r));
11208
11209                Binder.restoreCallingIdentity(origId);
11210            }
11211        }
11212    }
11213
11214    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
11215        synchronized(this) {
11216            if (!(token instanceof ServiceRecord)) {
11217                throw new IllegalArgumentException("Invalid service token");
11218            }
11219            ServiceRecord r = (ServiceRecord)token;
11220            boolean inStopping = mStoppingServices.contains(token);
11221            if (r != null) {
11222                if (DEBUG_SERVICE) Log.v(TAG, "DONE EXECUTING SERVICE " + r.name
11223                        + ": nesting=" + r.executeNesting
11224                        + ", inStopping=" + inStopping);
11225                if (r != token) {
11226                    Log.w(TAG, "Done executing service " + r.name
11227                          + " with incorrect token: given " + token
11228                          + ", expected " + r);
11229                    return;
11230                }
11231
11232                if (type == 1) {
11233                    // This is a call from a service start...  take care of
11234                    // book-keeping.
11235                    r.callStart = true;
11236                    switch (res) {
11237                        case Service.START_STICKY_COMPATIBILITY:
11238                        case Service.START_STICKY: {
11239                            // We are done with the associated start arguments.
11240                            r.findDeliveredStart(startId, true);
11241                            // Don't stop if killed.
11242                            r.stopIfKilled = false;
11243                            break;
11244                        }
11245                        case Service.START_NOT_STICKY: {
11246                            // We are done with the associated start arguments.
11247                            r.findDeliveredStart(startId, true);
11248                            if (r.lastStartId == startId) {
11249                                // There is no more work, and this service
11250                                // doesn't want to hang around if killed.
11251                                r.stopIfKilled = true;
11252                            }
11253                            break;
11254                        }
11255                        case Service.START_REDELIVER_INTENT: {
11256                            // We'll keep this item until they explicitly
11257                            // call stop for it, but keep track of the fact
11258                            // that it was delivered.
11259                            ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
11260                            if (si != null) {
11261                                si.deliveryCount = 0;
11262                                si.doneExecutingCount++;
11263                                // Don't stop if killed.
11264                                r.stopIfKilled = true;
11265                            }
11266                            break;
11267                        }
11268                        default:
11269                            throw new IllegalArgumentException(
11270                                    "Unknown service start result: " + res);
11271                    }
11272                    if (res == Service.START_STICKY_COMPATIBILITY) {
11273                        r.callStart = false;
11274                    }
11275                }
11276
11277                final long origId = Binder.clearCallingIdentity();
11278                serviceDoneExecutingLocked(r, inStopping);
11279                Binder.restoreCallingIdentity(origId);
11280            } else {
11281                Log.w(TAG, "Done executing unknown service " + r.name
11282                        + " with token " + token);
11283            }
11284        }
11285    }
11286
11287    public void serviceDoneExecutingLocked(ServiceRecord r, boolean inStopping) {
11288        r.executeNesting--;
11289        if (r.executeNesting <= 0 && r.app != null) {
11290            r.app.executingServices.remove(r);
11291            if (r.app.executingServices.size() == 0) {
11292                mHandler.removeMessages(SERVICE_TIMEOUT_MSG, r.app);
11293            }
11294            if (inStopping) {
11295                mStoppingServices.remove(r);
11296            }
11297            updateOomAdjLocked(r.app);
11298        }
11299    }
11300
11301    void serviceTimeout(ProcessRecord proc) {
11302        synchronized(this) {
11303            if (proc.executingServices.size() == 0 || proc.thread == null) {
11304                return;
11305            }
11306            long maxTime = SystemClock.uptimeMillis() - SERVICE_TIMEOUT;
11307            Iterator<ServiceRecord> it = proc.executingServices.iterator();
11308            ServiceRecord timeout = null;
11309            long nextTime = 0;
11310            while (it.hasNext()) {
11311                ServiceRecord sr = it.next();
11312                if (sr.executingStart < maxTime) {
11313                    timeout = sr;
11314                    break;
11315                }
11316                if (sr.executingStart > nextTime) {
11317                    nextTime = sr.executingStart;
11318                }
11319            }
11320            if (timeout != null && mLRUProcesses.contains(proc)) {
11321                Log.w(TAG, "Timeout executing service: " + timeout);
11322                appNotRespondingLocked(proc, null, null, "Executing service "
11323                        + timeout.name);
11324            } else {
11325                Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
11326                msg.obj = proc;
11327                mHandler.sendMessageAtTime(msg, nextTime+SERVICE_TIMEOUT);
11328            }
11329        }
11330    }
11331
11332    // =========================================================
11333    // BACKUP AND RESTORE
11334    // =========================================================
11335
11336    // Cause the target app to be launched if necessary and its backup agent
11337    // instantiated.  The backup agent will invoke backupAgentCreated() on the
11338    // activity manager to announce its creation.
11339    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
11340        if (DEBUG_BACKUP) Log.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode);
11341        enforceCallingPermission("android.permission.BACKUP", "startBackupAgent");
11342
11343        synchronized(this) {
11344            // !!! TODO: currently no check here that we're already bound
11345            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
11346            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11347            synchronized (stats) {
11348                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
11349            }
11350
11351            BackupRecord r = new BackupRecord(ss, app, backupMode);
11352            ComponentName hostingName = new ComponentName(app.packageName, app.backupAgentName);
11353            // startProcessLocked() returns existing proc's record if it's already running
11354            ProcessRecord proc = startProcessLocked(app.processName, app,
11355                    false, 0, "backup", hostingName, false);
11356            if (proc == null) {
11357                Log.e(TAG, "Unable to start backup agent process " + r);
11358                return false;
11359            }
11360
11361            r.app = proc;
11362            mBackupTarget = r;
11363            mBackupAppName = app.packageName;
11364
11365            // Try not to kill the process during backup
11366            updateOomAdjLocked(proc);
11367
11368            // If the process is already attached, schedule the creation of the backup agent now.
11369            // If it is not yet live, this will be done when it attaches to the framework.
11370            if (proc.thread != null) {
11371                if (DEBUG_BACKUP) Log.v(TAG, "Agent proc already running: " + proc);
11372                try {
11373                    proc.thread.scheduleCreateBackupAgent(app, backupMode);
11374                } catch (RemoteException e) {
11375                    // !!! TODO: notify the backup manager that we crashed, or rely on
11376                    // death notices, or...?
11377                }
11378            } else {
11379                if (DEBUG_BACKUP) Log.v(TAG, "Agent proc not running, waiting for attach");
11380            }
11381            // Invariants: at this point, the target app process exists and the application
11382            // is either already running or in the process of coming up.  mBackupTarget and
11383            // mBackupAppName describe the app, so that when it binds back to the AM we
11384            // know that it's scheduled for a backup-agent operation.
11385        }
11386
11387        return true;
11388    }
11389
11390    // A backup agent has just come up
11391    public void backupAgentCreated(String agentPackageName, IBinder agent) {
11392        if (DEBUG_BACKUP) Log.v(TAG, "backupAgentCreated: " + agentPackageName
11393                + " = " + agent);
11394
11395        synchronized(this) {
11396            if (!agentPackageName.equals(mBackupAppName)) {
11397                Log.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
11398                return;
11399            }
11400
11401            long oldIdent = Binder.clearCallingIdentity();
11402            try {
11403                IBackupManager bm = IBackupManager.Stub.asInterface(
11404                        ServiceManager.getService(Context.BACKUP_SERVICE));
11405                bm.agentConnected(agentPackageName, agent);
11406            } catch (RemoteException e) {
11407                // can't happen; the backup manager service is local
11408            } catch (Exception e) {
11409                Log.w(TAG, "Exception trying to deliver BackupAgent binding: ");
11410                e.printStackTrace();
11411            } finally {
11412                Binder.restoreCallingIdentity(oldIdent);
11413            }
11414        }
11415    }
11416
11417    // done with this agent
11418    public void unbindBackupAgent(ApplicationInfo appInfo) {
11419        if (DEBUG_BACKUP) Log.v(TAG, "unbindBackupAgent: " + appInfo);
11420        if (appInfo == null) {
11421            Log.w(TAG, "unbind backup agent for null app");
11422            return;
11423        }
11424
11425        synchronized(this) {
11426            if (mBackupAppName == null) {
11427                Log.w(TAG, "Unbinding backup agent with no active backup");
11428                return;
11429            }
11430
11431            if (!mBackupAppName.equals(appInfo.packageName)) {
11432                Log.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
11433                return;
11434            }
11435
11436            ProcessRecord proc = mBackupTarget.app;
11437            mBackupTarget = null;
11438            mBackupAppName = null;
11439
11440            // Not backing this app up any more; reset its OOM adjustment
11441            updateOomAdjLocked(proc);
11442
11443            // If the app crashed during backup, 'thread' will be null here
11444            if (proc.thread != null) {
11445                try {
11446                    proc.thread.scheduleDestroyBackupAgent(appInfo);
11447                } catch (Exception e) {
11448                    Log.e(TAG, "Exception when unbinding backup agent:");
11449                    e.printStackTrace();
11450                }
11451            }
11452        }
11453    }
11454    // =========================================================
11455    // BROADCASTS
11456    // =========================================================
11457
11458    private final List getStickies(String action, IntentFilter filter,
11459            List cur) {
11460        final ContentResolver resolver = mContext.getContentResolver();
11461        final ArrayList<Intent> list = mStickyBroadcasts.get(action);
11462        if (list == null) {
11463            return cur;
11464        }
11465        int N = list.size();
11466        for (int i=0; i<N; i++) {
11467            Intent intent = list.get(i);
11468            if (filter.match(resolver, intent, true, TAG) >= 0) {
11469                if (cur == null) {
11470                    cur = new ArrayList<Intent>();
11471                }
11472                cur.add(intent);
11473            }
11474        }
11475        return cur;
11476    }
11477
11478    private final void scheduleBroadcastsLocked() {
11479        if (DEBUG_BROADCAST) Log.v(TAG, "Schedule broadcasts: current="
11480                + mBroadcastsScheduled);
11481
11482        if (mBroadcastsScheduled) {
11483            return;
11484        }
11485        mHandler.sendEmptyMessage(BROADCAST_INTENT_MSG);
11486        mBroadcastsScheduled = true;
11487    }
11488
11489    public Intent registerReceiver(IApplicationThread caller,
11490            IIntentReceiver receiver, IntentFilter filter, String permission) {
11491        synchronized(this) {
11492            ProcessRecord callerApp = null;
11493            if (caller != null) {
11494                callerApp = getRecordForAppLocked(caller);
11495                if (callerApp == null) {
11496                    throw new SecurityException(
11497                            "Unable to find app for caller " + caller
11498                            + " (pid=" + Binder.getCallingPid()
11499                            + ") when registering receiver " + receiver);
11500                }
11501            }
11502
11503            List allSticky = null;
11504
11505            // Look for any matching sticky broadcasts...
11506            Iterator actions = filter.actionsIterator();
11507            if (actions != null) {
11508                while (actions.hasNext()) {
11509                    String action = (String)actions.next();
11510                    allSticky = getStickies(action, filter, allSticky);
11511                }
11512            } else {
11513                allSticky = getStickies(null, filter, allSticky);
11514            }
11515
11516            // The first sticky in the list is returned directly back to
11517            // the client.
11518            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
11519
11520            if (DEBUG_BROADCAST) Log.v(TAG, "Register receiver " + filter
11521                    + ": " + sticky);
11522
11523            if (receiver == null) {
11524                return sticky;
11525            }
11526
11527            ReceiverList rl
11528                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11529            if (rl == null) {
11530                rl = new ReceiverList(this, callerApp,
11531                        Binder.getCallingPid(),
11532                        Binder.getCallingUid(), receiver);
11533                if (rl.app != null) {
11534                    rl.app.receivers.add(rl);
11535                } else {
11536                    try {
11537                        receiver.asBinder().linkToDeath(rl, 0);
11538                    } catch (RemoteException e) {
11539                        return sticky;
11540                    }
11541                    rl.linkedToDeath = true;
11542                }
11543                mRegisteredReceivers.put(receiver.asBinder(), rl);
11544            }
11545            BroadcastFilter bf = new BroadcastFilter(filter, rl, permission);
11546            rl.add(bf);
11547            if (!bf.debugCheck()) {
11548                Log.w(TAG, "==> For Dynamic broadast");
11549            }
11550            mReceiverResolver.addFilter(bf);
11551
11552            // Enqueue broadcasts for all existing stickies that match
11553            // this filter.
11554            if (allSticky != null) {
11555                ArrayList receivers = new ArrayList();
11556                receivers.add(bf);
11557
11558                int N = allSticky.size();
11559                for (int i=0; i<N; i++) {
11560                    Intent intent = (Intent)allSticky.get(i);
11561                    BroadcastRecord r = new BroadcastRecord(intent, null,
11562                            null, -1, -1, null, receivers, null, 0, null, null,
11563                            false);
11564                    if (mParallelBroadcasts.size() == 0) {
11565                        scheduleBroadcastsLocked();
11566                    }
11567                    mParallelBroadcasts.add(r);
11568                }
11569            }
11570
11571            return sticky;
11572        }
11573    }
11574
11575    public void unregisterReceiver(IIntentReceiver receiver) {
11576        if (DEBUG_BROADCAST) Log.v(TAG, "Unregister receiver: " + receiver);
11577
11578        boolean doNext = false;
11579
11580        synchronized(this) {
11581            ReceiverList rl
11582                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11583            if (rl != null) {
11584                if (rl.curBroadcast != null) {
11585                    BroadcastRecord r = rl.curBroadcast;
11586                    doNext = finishReceiverLocked(
11587                        receiver.asBinder(), r.resultCode, r.resultData,
11588                        r.resultExtras, r.resultAbort, true);
11589                }
11590
11591                if (rl.app != null) {
11592                    rl.app.receivers.remove(rl);
11593                }
11594                removeReceiverLocked(rl);
11595                if (rl.linkedToDeath) {
11596                    rl.linkedToDeath = false;
11597                    rl.receiver.asBinder().unlinkToDeath(rl, 0);
11598                }
11599            }
11600        }
11601
11602        if (!doNext) {
11603            return;
11604        }
11605
11606        final long origId = Binder.clearCallingIdentity();
11607        processNextBroadcast(false);
11608        trimApplications();
11609        Binder.restoreCallingIdentity(origId);
11610    }
11611
11612    void removeReceiverLocked(ReceiverList rl) {
11613        mRegisteredReceivers.remove(rl.receiver.asBinder());
11614        int N = rl.size();
11615        for (int i=0; i<N; i++) {
11616            mReceiverResolver.removeFilter(rl.get(i));
11617        }
11618    }
11619
11620    private final int broadcastIntentLocked(ProcessRecord callerApp,
11621            String callerPackage, Intent intent, String resolvedType,
11622            IIntentReceiver resultTo, int resultCode, String resultData,
11623            Bundle map, String requiredPermission,
11624            boolean ordered, boolean sticky, int callingPid, int callingUid) {
11625        intent = new Intent(intent);
11626
11627        if (DEBUG_BROADCAST_LIGHT) Log.v(
11628            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
11629            + " ordered=" + ordered);
11630        if ((resultTo != null) && !ordered) {
11631            Log.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
11632        }
11633
11634        // Handle special intents: if this broadcast is from the package
11635        // manager about a package being removed, we need to remove all of
11636        // its activities from the history stack.
11637        final boolean uidRemoved = intent.ACTION_UID_REMOVED.equals(
11638                intent.getAction());
11639        if (intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
11640                || intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
11641                || uidRemoved) {
11642            if (checkComponentPermission(
11643                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
11644                    callingPid, callingUid, -1)
11645                    == PackageManager.PERMISSION_GRANTED) {
11646                if (uidRemoved) {
11647                    final Bundle intentExtras = intent.getExtras();
11648                    final int uid = intentExtras != null
11649                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
11650                    if (uid >= 0) {
11651                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
11652                        synchronized (bs) {
11653                            bs.removeUidStatsLocked(uid);
11654                        }
11655                    }
11656                } else {
11657                    Uri data = intent.getData();
11658                    String ssp;
11659                    if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11660                        if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
11661                            uninstallPackageLocked(ssp,
11662                                    intent.getIntExtra(Intent.EXTRA_UID, -1), false);
11663                            AttributeCache ac = AttributeCache.instance();
11664                            if (ac != null) {
11665                                ac.removePackage(ssp);
11666                            }
11667                        }
11668                    }
11669                }
11670            } else {
11671                String msg = "Permission Denial: " + intent.getAction()
11672                        + " broadcast from " + callerPackage + " (pid=" + callingPid
11673                        + ", uid=" + callingUid + ")"
11674                        + " requires "
11675                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
11676                Log.w(TAG, msg);
11677                throw new SecurityException(msg);
11678            }
11679        }
11680
11681        /*
11682         * If this is the time zone changed action, queue up a message that will reset the timezone
11683         * of all currently running processes. This message will get queued up before the broadcast
11684         * happens.
11685         */
11686        if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
11687            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
11688        }
11689
11690        /*
11691         * Prevent non-system code (defined here to be non-persistent
11692         * processes) from sending protected broadcasts.
11693         */
11694        if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID
11695                || callingUid == Process.SHELL_UID || callingUid == 0) {
11696            // Always okay.
11697        } else if (callerApp == null || !callerApp.persistent) {
11698            try {
11699                if (ActivityThread.getPackageManager().isProtectedBroadcast(
11700                        intent.getAction())) {
11701                    String msg = "Permission Denial: not allowed to send broadcast "
11702                            + intent.getAction() + " from pid="
11703                            + callingPid + ", uid=" + callingUid;
11704                    Log.w(TAG, msg);
11705                    throw new SecurityException(msg);
11706                }
11707            } catch (RemoteException e) {
11708                Log.w(TAG, "Remote exception", e);
11709                return BROADCAST_SUCCESS;
11710            }
11711        }
11712
11713        // Add to the sticky list if requested.
11714        if (sticky) {
11715            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
11716                    callingPid, callingUid)
11717                    != PackageManager.PERMISSION_GRANTED) {
11718                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
11719                        + callingPid + ", uid=" + callingUid
11720                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
11721                Log.w(TAG, msg);
11722                throw new SecurityException(msg);
11723            }
11724            if (requiredPermission != null) {
11725                Log.w(TAG, "Can't broadcast sticky intent " + intent
11726                        + " and enforce permission " + requiredPermission);
11727                return BROADCAST_STICKY_CANT_HAVE_PERMISSION;
11728            }
11729            if (intent.getComponent() != null) {
11730                throw new SecurityException(
11731                        "Sticky broadcasts can't target a specific component");
11732            }
11733            ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
11734            if (list == null) {
11735                list = new ArrayList<Intent>();
11736                mStickyBroadcasts.put(intent.getAction(), list);
11737            }
11738            int N = list.size();
11739            int i;
11740            for (i=0; i<N; i++) {
11741                if (intent.filterEquals(list.get(i))) {
11742                    // This sticky already exists, replace it.
11743                    list.set(i, new Intent(intent));
11744                    break;
11745                }
11746            }
11747            if (i >= N) {
11748                list.add(new Intent(intent));
11749            }
11750        }
11751
11752        // Figure out who all will receive this broadcast.
11753        List receivers = null;
11754        List<BroadcastFilter> registeredReceivers = null;
11755        try {
11756            if (intent.getComponent() != null) {
11757                // Broadcast is going to one specific receiver class...
11758                ActivityInfo ai = ActivityThread.getPackageManager().
11759                    getReceiverInfo(intent.getComponent(), STOCK_PM_FLAGS);
11760                if (ai != null) {
11761                    receivers = new ArrayList();
11762                    ResolveInfo ri = new ResolveInfo();
11763                    ri.activityInfo = ai;
11764                    receivers.add(ri);
11765                }
11766            } else {
11767                // Need to resolve the intent to interested receivers...
11768                if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
11769                         == 0) {
11770                    receivers =
11771                        ActivityThread.getPackageManager().queryIntentReceivers(
11772                                intent, resolvedType, STOCK_PM_FLAGS);
11773                }
11774                registeredReceivers = mReceiverResolver.queryIntent(intent, resolvedType, false);
11775            }
11776        } catch (RemoteException ex) {
11777            // pm is in same process, this will never happen.
11778        }
11779
11780        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
11781        if (!ordered && NR > 0) {
11782            // If we are not serializing this broadcast, then send the
11783            // registered receivers separately so they don't wait for the
11784            // components to be launched.
11785            BroadcastRecord r = new BroadcastRecord(intent, callerApp,
11786                    callerPackage, callingPid, callingUid, requiredPermission,
11787                    registeredReceivers, resultTo, resultCode, resultData, map,
11788                    ordered);
11789            if (DEBUG_BROADCAST) Log.v(
11790                    TAG, "Enqueueing parallel broadcast " + r
11791                    + ": prev had " + mParallelBroadcasts.size());
11792            mParallelBroadcasts.add(r);
11793            scheduleBroadcastsLocked();
11794            registeredReceivers = null;
11795            NR = 0;
11796        }
11797
11798        // Merge into one list.
11799        int ir = 0;
11800        if (receivers != null) {
11801            // A special case for PACKAGE_ADDED: do not allow the package
11802            // being added to see this broadcast.  This prevents them from
11803            // using this as a back door to get run as soon as they are
11804            // installed.  Maybe in the future we want to have a special install
11805            // broadcast or such for apps, but we'd like to deliberately make
11806            // this decision.
11807            boolean skip = false;
11808            if (intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
11809                skip = true;
11810            } else if (intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())) {
11811                skip = true;
11812            } else if (intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
11813                skip = true;
11814            }
11815            String skipPackage = (skip && intent.getData() != null)
11816                    ? intent.getData().getSchemeSpecificPart()
11817                    : null;
11818            if (skipPackage != null && receivers != null) {
11819                int NT = receivers.size();
11820                for (int it=0; it<NT; it++) {
11821                    ResolveInfo curt = (ResolveInfo)receivers.get(it);
11822                    if (curt.activityInfo.packageName.equals(skipPackage)) {
11823                        receivers.remove(it);
11824                        it--;
11825                        NT--;
11826                    }
11827                }
11828            }
11829
11830            int NT = receivers != null ? receivers.size() : 0;
11831            int it = 0;
11832            ResolveInfo curt = null;
11833            BroadcastFilter curr = null;
11834            while (it < NT && ir < NR) {
11835                if (curt == null) {
11836                    curt = (ResolveInfo)receivers.get(it);
11837                }
11838                if (curr == null) {
11839                    curr = registeredReceivers.get(ir);
11840                }
11841                if (curr.getPriority() >= curt.priority) {
11842                    // Insert this broadcast record into the final list.
11843                    receivers.add(it, curr);
11844                    ir++;
11845                    curr = null;
11846                    it++;
11847                    NT++;
11848                } else {
11849                    // Skip to the next ResolveInfo in the final list.
11850                    it++;
11851                    curt = null;
11852                }
11853            }
11854        }
11855        while (ir < NR) {
11856            if (receivers == null) {
11857                receivers = new ArrayList();
11858            }
11859            receivers.add(registeredReceivers.get(ir));
11860            ir++;
11861        }
11862
11863        if ((receivers != null && receivers.size() > 0)
11864                || resultTo != null) {
11865            BroadcastRecord r = new BroadcastRecord(intent, callerApp,
11866                    callerPackage, callingPid, callingUid, requiredPermission,
11867                    receivers, resultTo, resultCode, resultData, map, ordered);
11868            if (DEBUG_BROADCAST) Log.v(
11869                    TAG, "Enqueueing ordered broadcast " + r
11870                    + ": prev had " + mOrderedBroadcasts.size());
11871            if (DEBUG_BROADCAST) {
11872                int seq = r.intent.getIntExtra("seq", -1);
11873                Log.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
11874            }
11875            mOrderedBroadcasts.add(r);
11876            scheduleBroadcastsLocked();
11877        }
11878
11879        return BROADCAST_SUCCESS;
11880    }
11881
11882    public final int broadcastIntent(IApplicationThread caller,
11883            Intent intent, String resolvedType, IIntentReceiver resultTo,
11884            int resultCode, String resultData, Bundle map,
11885            String requiredPermission, boolean serialized, boolean sticky) {
11886        // Refuse possible leaked file descriptors
11887        if (intent != null && intent.hasFileDescriptors() == true) {
11888            throw new IllegalArgumentException("File descriptors passed in Intent");
11889        }
11890
11891        synchronized(this) {
11892            int flags = intent.getFlags();
11893
11894            if (!mSystemReady) {
11895                // if the caller really truly claims to know what they're doing, go
11896                // ahead and allow the broadcast without launching any receivers
11897                if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
11898                    intent = new Intent(intent);
11899                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11900                } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0){
11901                    Log.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
11902                            + " before boot completion");
11903                    throw new IllegalStateException("Cannot broadcast before boot completed");
11904                }
11905            }
11906
11907            if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
11908                throw new IllegalArgumentException(
11909                        "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
11910            }
11911
11912            final ProcessRecord callerApp = getRecordForAppLocked(caller);
11913            final int callingPid = Binder.getCallingPid();
11914            final int callingUid = Binder.getCallingUid();
11915            final long origId = Binder.clearCallingIdentity();
11916            int res = broadcastIntentLocked(callerApp,
11917                    callerApp != null ? callerApp.info.packageName : null,
11918                    intent, resolvedType, resultTo,
11919                    resultCode, resultData, map, requiredPermission, serialized,
11920                    sticky, callingPid, callingUid);
11921            Binder.restoreCallingIdentity(origId);
11922            return res;
11923        }
11924    }
11925
11926    int broadcastIntentInPackage(String packageName, int uid,
11927            Intent intent, String resolvedType, IIntentReceiver resultTo,
11928            int resultCode, String resultData, Bundle map,
11929            String requiredPermission, boolean serialized, boolean sticky) {
11930        synchronized(this) {
11931            final long origId = Binder.clearCallingIdentity();
11932            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
11933                    resultTo, resultCode, resultData, map, requiredPermission,
11934                    serialized, sticky, -1, uid);
11935            Binder.restoreCallingIdentity(origId);
11936            return res;
11937        }
11938    }
11939
11940    public final void unbroadcastIntent(IApplicationThread caller,
11941            Intent intent) {
11942        // Refuse possible leaked file descriptors
11943        if (intent != null && intent.hasFileDescriptors() == true) {
11944            throw new IllegalArgumentException("File descriptors passed in Intent");
11945        }
11946
11947        synchronized(this) {
11948            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
11949                    != PackageManager.PERMISSION_GRANTED) {
11950                String msg = "Permission Denial: unbroadcastIntent() from pid="
11951                        + Binder.getCallingPid()
11952                        + ", uid=" + Binder.getCallingUid()
11953                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
11954                Log.w(TAG, msg);
11955                throw new SecurityException(msg);
11956            }
11957            ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
11958            if (list != null) {
11959                int N = list.size();
11960                int i;
11961                for (i=0; i<N; i++) {
11962                    if (intent.filterEquals(list.get(i))) {
11963                        list.remove(i);
11964                        break;
11965                    }
11966                }
11967            }
11968        }
11969    }
11970
11971    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
11972            String resultData, Bundle resultExtras, boolean resultAbort,
11973            boolean explicit) {
11974        if (mOrderedBroadcasts.size() == 0) {
11975            if (explicit) {
11976                Log.w(TAG, "finishReceiver called but no pending broadcasts");
11977            }
11978            return false;
11979        }
11980        BroadcastRecord r = mOrderedBroadcasts.get(0);
11981        if (r.receiver == null) {
11982            if (explicit) {
11983                Log.w(TAG, "finishReceiver called but none active");
11984            }
11985            return false;
11986        }
11987        if (r.receiver != receiver) {
11988            Log.w(TAG, "finishReceiver called but active receiver is different");
11989            return false;
11990        }
11991        int state = r.state;
11992        r.state = r.IDLE;
11993        if (state == r.IDLE) {
11994            if (explicit) {
11995                Log.w(TAG, "finishReceiver called but state is IDLE");
11996            }
11997        }
11998        r.receiver = null;
11999        r.intent.setComponent(null);
12000        if (r.curApp != null) {
12001            r.curApp.curReceiver = null;
12002        }
12003        if (r.curFilter != null) {
12004            r.curFilter.receiverList.curBroadcast = null;
12005        }
12006        r.curFilter = null;
12007        r.curApp = null;
12008        r.curComponent = null;
12009        r.curReceiver = null;
12010        mPendingBroadcast = null;
12011
12012        r.resultCode = resultCode;
12013        r.resultData = resultData;
12014        r.resultExtras = resultExtras;
12015        r.resultAbort = resultAbort;
12016
12017        // We will process the next receiver right now if this is finishing
12018        // an app receiver (which is always asynchronous) or after we have
12019        // come back from calling a receiver.
12020        return state == BroadcastRecord.APP_RECEIVE
12021                || state == BroadcastRecord.CALL_DONE_RECEIVE;
12022    }
12023
12024    public void finishReceiver(IBinder who, int resultCode, String resultData,
12025            Bundle resultExtras, boolean resultAbort) {
12026        if (DEBUG_BROADCAST) Log.v(TAG, "Finish receiver: " + who);
12027
12028        // Refuse possible leaked file descriptors
12029        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
12030            throw new IllegalArgumentException("File descriptors passed in Bundle");
12031        }
12032
12033        boolean doNext;
12034
12035        final long origId = Binder.clearCallingIdentity();
12036
12037        synchronized(this) {
12038            doNext = finishReceiverLocked(
12039                who, resultCode, resultData, resultExtras, resultAbort, true);
12040        }
12041
12042        if (doNext) {
12043            processNextBroadcast(false);
12044        }
12045        trimApplications();
12046
12047        Binder.restoreCallingIdentity(origId);
12048    }
12049
12050    private final void logBroadcastReceiverDiscard(BroadcastRecord r) {
12051        if (r.nextReceiver > 0) {
12052            Object curReceiver = r.receivers.get(r.nextReceiver-1);
12053            if (curReceiver instanceof BroadcastFilter) {
12054                BroadcastFilter bf = (BroadcastFilter) curReceiver;
12055                EventLog.writeEvent(LOG_AM_BROADCAST_DISCARD_FILTER,
12056                        System.identityHashCode(r),
12057                        r.intent.getAction(),
12058                        r.nextReceiver - 1,
12059                        System.identityHashCode(bf));
12060            } else {
12061                EventLog.writeEvent(LOG_AM_BROADCAST_DISCARD_APP,
12062                        System.identityHashCode(r),
12063                        r.intent.getAction(),
12064                        r.nextReceiver - 1,
12065                        ((ResolveInfo)curReceiver).toString());
12066            }
12067        } else {
12068            Log.w(TAG, "Discarding broadcast before first receiver is invoked: "
12069                    + r);
12070            EventLog.writeEvent(LOG_AM_BROADCAST_DISCARD_APP,
12071                    System.identityHashCode(r),
12072                    r.intent.getAction(),
12073                    r.nextReceiver,
12074                    "NONE");
12075        }
12076    }
12077
12078    private final void broadcastTimeout() {
12079        synchronized (this) {
12080            if (mOrderedBroadcasts.size() == 0) {
12081                return;
12082            }
12083            long now = SystemClock.uptimeMillis();
12084            BroadcastRecord r = mOrderedBroadcasts.get(0);
12085            if ((r.startTime+BROADCAST_TIMEOUT) > now) {
12086                if (DEBUG_BROADCAST) Log.v(TAG,
12087                        "Premature timeout @ " + now + ": resetting BROADCAST_TIMEOUT_MSG for "
12088                        + (r.startTime + BROADCAST_TIMEOUT));
12089                Message msg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG);
12090                mHandler.sendMessageAtTime(msg, r.startTime+BROADCAST_TIMEOUT);
12091                return;
12092            }
12093
12094            Log.w(TAG, "Timeout of broadcast " + r + " - receiver=" + r.receiver);
12095            r.startTime = now;
12096            r.anrCount++;
12097
12098            // Current receiver has passed its expiration date.
12099            if (r.nextReceiver <= 0) {
12100                Log.w(TAG, "Timeout on receiver with nextReceiver <= 0");
12101                return;
12102            }
12103
12104            ProcessRecord app = null;
12105
12106            Object curReceiver = r.receivers.get(r.nextReceiver-1);
12107            Log.w(TAG, "Receiver during timeout: " + curReceiver);
12108            logBroadcastReceiverDiscard(r);
12109            if (curReceiver instanceof BroadcastFilter) {
12110                BroadcastFilter bf = (BroadcastFilter)curReceiver;
12111                if (bf.receiverList.pid != 0
12112                        && bf.receiverList.pid != MY_PID) {
12113                    synchronized (this.mPidsSelfLocked) {
12114                        app = this.mPidsSelfLocked.get(
12115                                bf.receiverList.pid);
12116                    }
12117                }
12118            } else {
12119                app = r.curApp;
12120            }
12121
12122            if (app != null) {
12123                appNotRespondingLocked(app, null, null,
12124                        "Broadcast of " + r.intent.toString());
12125            }
12126
12127            if (mPendingBroadcast == r) {
12128                mPendingBroadcast = null;
12129            }
12130
12131            // Move on to the next receiver.
12132            finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
12133                    r.resultExtras, r.resultAbort, true);
12134            scheduleBroadcastsLocked();
12135        }
12136    }
12137
12138    private final void processCurBroadcastLocked(BroadcastRecord r,
12139            ProcessRecord app) throws RemoteException {
12140        if (app.thread == null) {
12141            throw new RemoteException();
12142        }
12143        r.receiver = app.thread.asBinder();
12144        r.curApp = app;
12145        app.curReceiver = r;
12146        updateLRUListLocked(app, true);
12147
12148        // Tell the application to launch this receiver.
12149        r.intent.setComponent(r.curComponent);
12150
12151        boolean started = false;
12152        try {
12153            if (DEBUG_BROADCAST_LIGHT) Log.v(TAG,
12154                    "Delivering to component " + r.curComponent
12155                    + ": " + r);
12156            ensurePackageDexOpt(r.intent.getComponent().getPackageName());
12157            app.thread.scheduleReceiver(new Intent(r.intent), r.curReceiver,
12158                    r.resultCode, r.resultData, r.resultExtras, r.ordered);
12159            started = true;
12160        } finally {
12161            if (!started) {
12162                r.receiver = null;
12163                r.curApp = null;
12164                app.curReceiver = null;
12165            }
12166        }
12167
12168    }
12169
12170    static void performReceive(ProcessRecord app, IIntentReceiver receiver,
12171            Intent intent, int resultCode, String data,
12172            Bundle extras, boolean ordered) throws RemoteException {
12173        if (app != null && app.thread != null) {
12174            // If we have an app thread, do the call through that so it is
12175            // correctly ordered with other one-way calls.
12176            app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
12177                    data, extras, ordered);
12178        } else {
12179            receiver.performReceive(intent, resultCode, data, extras, ordered);
12180        }
12181    }
12182
12183    private final void deliverToRegisteredReceiver(BroadcastRecord r,
12184            BroadcastFilter filter, boolean ordered) {
12185        boolean skip = false;
12186        if (filter.requiredPermission != null) {
12187            int perm = checkComponentPermission(filter.requiredPermission,
12188                    r.callingPid, r.callingUid, -1);
12189            if (perm != PackageManager.PERMISSION_GRANTED) {
12190                Log.w(TAG, "Permission Denial: broadcasting "
12191                        + r.intent.toString()
12192                        + " from " + r.callerPackage + " (pid="
12193                        + r.callingPid + ", uid=" + r.callingUid + ")"
12194                        + " requires " + filter.requiredPermission
12195                        + " due to registered receiver " + filter);
12196                skip = true;
12197            }
12198        }
12199        if (r.requiredPermission != null) {
12200            int perm = checkComponentPermission(r.requiredPermission,
12201                    filter.receiverList.pid, filter.receiverList.uid, -1);
12202            if (perm != PackageManager.PERMISSION_GRANTED) {
12203                Log.w(TAG, "Permission Denial: receiving "
12204                        + r.intent.toString()
12205                        + " to " + filter.receiverList.app
12206                        + " (pid=" + filter.receiverList.pid
12207                        + ", uid=" + filter.receiverList.uid + ")"
12208                        + " requires " + r.requiredPermission
12209                        + " due to sender " + r.callerPackage
12210                        + " (uid " + r.callingUid + ")");
12211                skip = true;
12212            }
12213        }
12214
12215        if (!skip) {
12216            // If this is not being sent as an ordered broadcast, then we
12217            // don't want to touch the fields that keep track of the current
12218            // state of ordered broadcasts.
12219            if (ordered) {
12220                r.receiver = filter.receiverList.receiver.asBinder();
12221                r.curFilter = filter;
12222                filter.receiverList.curBroadcast = r;
12223                r.state = BroadcastRecord.CALL_IN_RECEIVE;
12224                if (filter.receiverList.app != null) {
12225                    // Bump hosting application to no longer be in background
12226                    // scheduling class.  Note that we can't do that if there
12227                    // isn't an app...  but we can only be in that case for
12228                    // things that directly call the IActivityManager API, which
12229                    // are already core system stuff so don't matter for this.
12230                    r.curApp = filter.receiverList.app;
12231                    filter.receiverList.app.curReceiver = r;
12232                    updateOomAdjLocked();
12233                }
12234            }
12235            try {
12236                if (DEBUG_BROADCAST_LIGHT) {
12237                    int seq = r.intent.getIntExtra("seq", -1);
12238                    Log.i(TAG, "Delivering to " + filter.receiverList.app
12239                            + " (seq=" + seq + "): " + r);
12240                }
12241                performReceive(filter.receiverList.app, filter.receiverList.receiver,
12242                    new Intent(r.intent), r.resultCode,
12243                    r.resultData, r.resultExtras, r.ordered);
12244                if (ordered) {
12245                    r.state = BroadcastRecord.CALL_DONE_RECEIVE;
12246                }
12247            } catch (RemoteException e) {
12248                Log.w(TAG, "Failure sending broadcast " + r.intent, e);
12249                if (ordered) {
12250                    r.receiver = null;
12251                    r.curFilter = null;
12252                    filter.receiverList.curBroadcast = null;
12253                    if (filter.receiverList.app != null) {
12254                        filter.receiverList.app.curReceiver = null;
12255                    }
12256                }
12257            }
12258        }
12259    }
12260
12261    private final void processNextBroadcast(boolean fromMsg) {
12262        synchronized(this) {
12263            BroadcastRecord r;
12264
12265            if (DEBUG_BROADCAST) Log.v(TAG, "processNextBroadcast: "
12266                    + mParallelBroadcasts.size() + " broadcasts, "
12267                    + mOrderedBroadcasts.size() + " serialized broadcasts");
12268
12269            updateCpuStats();
12270
12271            if (fromMsg) {
12272                mBroadcastsScheduled = false;
12273            }
12274
12275            // First, deliver any non-serialized broadcasts right away.
12276            while (mParallelBroadcasts.size() > 0) {
12277                r = mParallelBroadcasts.remove(0);
12278                final int N = r.receivers.size();
12279                if (DEBUG_BROADCAST_LIGHT) Log.v(TAG, "Processing parallel broadcast "
12280                        + r);
12281                for (int i=0; i<N; i++) {
12282                    Object target = r.receivers.get(i);
12283                    if (DEBUG_BROADCAST)  Log.v(TAG,
12284                            "Delivering non-serialized to registered "
12285                            + target + ": " + r);
12286                    deliverToRegisteredReceiver(r, (BroadcastFilter)target, false);
12287                }
12288                if (DEBUG_BROADCAST_LIGHT) Log.v(TAG, "Done with parallel broadcast "
12289                        + r);
12290            }
12291
12292            // Now take care of the next serialized one...
12293
12294            // If we are waiting for a process to come up to handle the next
12295            // broadcast, then do nothing at this point.  Just in case, we
12296            // check that the process we're waiting for still exists.
12297            if (mPendingBroadcast != null) {
12298                Log.i(TAG, "processNextBroadcast: waiting for "
12299                        + mPendingBroadcast.curApp);
12300
12301                boolean isDead;
12302                synchronized (mPidsSelfLocked) {
12303                    isDead = (mPidsSelfLocked.get(mPendingBroadcast.curApp.pid) == null);
12304                }
12305                if (!isDead) {
12306                    // It's still alive, so keep waiting
12307                    return;
12308                } else {
12309                    Log.w(TAG, "pending app " + mPendingBroadcast.curApp
12310                            + " died before responding to broadcast");
12311                    mPendingBroadcast = null;
12312                }
12313            }
12314
12315            boolean looped = false;
12316
12317            do {
12318                if (mOrderedBroadcasts.size() == 0) {
12319                    // No more broadcasts pending, so all done!
12320                    scheduleAppGcsLocked();
12321                    if (looped) {
12322                        // If we had finished the last ordered broadcast, then
12323                        // make sure all processes have correct oom and sched
12324                        // adjustments.
12325                        updateOomAdjLocked();
12326                    }
12327                    return;
12328                }
12329                r = mOrderedBroadcasts.get(0);
12330                boolean forceReceive = false;
12331
12332                // Ensure that even if something goes awry with the timeout
12333                // detection, we catch "hung" broadcasts here, discard them,
12334                // and continue to make progress.
12335                int numReceivers = (r.receivers != null) ? r.receivers.size() : 0;
12336                long now = SystemClock.uptimeMillis();
12337                if (r.dispatchTime > 0) {
12338                    if ((numReceivers > 0) &&
12339                            (now > r.dispatchTime + (2*BROADCAST_TIMEOUT*numReceivers))) {
12340                        Log.w(TAG, "Hung broadcast discarded after timeout failure:"
12341                                + " now=" + now
12342                                + " dispatchTime=" + r.dispatchTime
12343                                + " startTime=" + r.startTime
12344                                + " intent=" + r.intent
12345                                + " numReceivers=" + numReceivers
12346                                + " nextReceiver=" + r.nextReceiver
12347                                + " state=" + r.state);
12348                        broadcastTimeout(); // forcibly finish this broadcast
12349                        forceReceive = true;
12350                        r.state = BroadcastRecord.IDLE;
12351                    }
12352                }
12353
12354                if (r.state != BroadcastRecord.IDLE) {
12355                    if (DEBUG_BROADCAST) Log.d(TAG,
12356                            "processNextBroadcast() called when not idle (state="
12357                            + r.state + ")");
12358                    return;
12359                }
12360
12361                if (r.receivers == null || r.nextReceiver >= numReceivers
12362                        || r.resultAbort || forceReceive) {
12363                    // No more receivers for this broadcast!  Send the final
12364                    // result if requested...
12365                    if (r.resultTo != null) {
12366                        try {
12367                            if (DEBUG_BROADCAST) {
12368                                int seq = r.intent.getIntExtra("seq", -1);
12369                                Log.i(TAG, "Finishing broadcast " + r.intent.getAction()
12370                                        + " seq=" + seq + " app=" + r.callerApp);
12371                            }
12372                            performReceive(r.callerApp, r.resultTo,
12373                                new Intent(r.intent), r.resultCode,
12374                                r.resultData, r.resultExtras, false);
12375                        } catch (RemoteException e) {
12376                            Log.w(TAG, "Failure sending broadcast result of " + r.intent, e);
12377                        }
12378                    }
12379
12380                    if (DEBUG_BROADCAST) Log.v(TAG, "Cancelling BROADCAST_TIMEOUT_MSG");
12381                    mHandler.removeMessages(BROADCAST_TIMEOUT_MSG);
12382
12383                    if (DEBUG_BROADCAST_LIGHT) Log.v(TAG, "Finished with ordered broadcast "
12384                            + r);
12385
12386                    // ... and on to the next...
12387                    mOrderedBroadcasts.remove(0);
12388                    r = null;
12389                    looped = true;
12390                    continue;
12391                }
12392            } while (r == null);
12393
12394            // Get the next receiver...
12395            int recIdx = r.nextReceiver++;
12396
12397            // Keep track of when this receiver started, and make sure there
12398            // is a timeout message pending to kill it if need be.
12399            r.startTime = SystemClock.uptimeMillis();
12400            if (recIdx == 0) {
12401                r.dispatchTime = r.startTime;
12402
12403                if (DEBUG_BROADCAST_LIGHT) Log.v(TAG, "Processing ordered broadcast "
12404                        + r);
12405                if (DEBUG_BROADCAST) Log.v(TAG,
12406                        "Submitting BROADCAST_TIMEOUT_MSG for "
12407                        + (r.startTime + BROADCAST_TIMEOUT));
12408                Message msg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG);
12409                mHandler.sendMessageAtTime(msg, r.startTime+BROADCAST_TIMEOUT);
12410            }
12411
12412            Object nextReceiver = r.receivers.get(recIdx);
12413            if (nextReceiver instanceof BroadcastFilter) {
12414                // Simple case: this is a registered receiver who gets
12415                // a direct call.
12416                BroadcastFilter filter = (BroadcastFilter)nextReceiver;
12417                if (DEBUG_BROADCAST)  Log.v(TAG,
12418                        "Delivering serialized to registered "
12419                        + filter + ": " + r);
12420                deliverToRegisteredReceiver(r, filter, r.ordered);
12421                if (r.receiver == null || !r.ordered) {
12422                    // The receiver has already finished, so schedule to
12423                    // process the next one.
12424                    r.state = BroadcastRecord.IDLE;
12425                    scheduleBroadcastsLocked();
12426                }
12427                return;
12428            }
12429
12430            // Hard case: need to instantiate the receiver, possibly
12431            // starting its application process to host it.
12432
12433            ResolveInfo info =
12434                (ResolveInfo)nextReceiver;
12435
12436            boolean skip = false;
12437            int perm = checkComponentPermission(info.activityInfo.permission,
12438                    r.callingPid, r.callingUid,
12439                    info.activityInfo.exported
12440                            ? -1 : info.activityInfo.applicationInfo.uid);
12441            if (perm != PackageManager.PERMISSION_GRANTED) {
12442                Log.w(TAG, "Permission Denial: broadcasting "
12443                        + r.intent.toString()
12444                        + " from " + r.callerPackage + " (pid=" + r.callingPid
12445                        + ", uid=" + r.callingUid + ")"
12446                        + " requires " + info.activityInfo.permission
12447                        + " due to receiver " + info.activityInfo.packageName
12448                        + "/" + info.activityInfo.name);
12449                skip = true;
12450            }
12451            if (r.callingUid != Process.SYSTEM_UID &&
12452                r.requiredPermission != null) {
12453                try {
12454                    perm = ActivityThread.getPackageManager().
12455                            checkPermission(r.requiredPermission,
12456                                    info.activityInfo.applicationInfo.packageName);
12457                } catch (RemoteException e) {
12458                    perm = PackageManager.PERMISSION_DENIED;
12459                }
12460                if (perm != PackageManager.PERMISSION_GRANTED) {
12461                    Log.w(TAG, "Permission Denial: receiving "
12462                            + r.intent + " to "
12463                            + info.activityInfo.applicationInfo.packageName
12464                            + " requires " + r.requiredPermission
12465                            + " due to sender " + r.callerPackage
12466                            + " (uid " + r.callingUid + ")");
12467                    skip = true;
12468                }
12469            }
12470            if (r.curApp != null && r.curApp.crashing) {
12471                // If the target process is crashing, just skip it.
12472                skip = true;
12473            }
12474
12475            if (skip) {
12476                r.receiver = null;
12477                r.curFilter = null;
12478                r.state = BroadcastRecord.IDLE;
12479                scheduleBroadcastsLocked();
12480                return;
12481            }
12482
12483            r.state = BroadcastRecord.APP_RECEIVE;
12484            String targetProcess = info.activityInfo.processName;
12485            r.curComponent = new ComponentName(
12486                    info.activityInfo.applicationInfo.packageName,
12487                    info.activityInfo.name);
12488            r.curReceiver = info.activityInfo;
12489
12490            // Is this receiver's application already running?
12491            ProcessRecord app = getProcessRecordLocked(targetProcess,
12492                    info.activityInfo.applicationInfo.uid);
12493            if (app != null && app.thread != null) {
12494                try {
12495                    processCurBroadcastLocked(r, app);
12496                    return;
12497                } catch (RemoteException e) {
12498                    Log.w(TAG, "Exception when sending broadcast to "
12499                          + r.curComponent, e);
12500                }
12501
12502                // If a dead object exception was thrown -- fall through to
12503                // restart the application.
12504            }
12505
12506            // Not running -- get it started, to be executed when the app comes up.
12507            if ((r.curApp=startProcessLocked(targetProcess,
12508                    info.activityInfo.applicationInfo, true,
12509                    r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND,
12510                    "broadcast", r.curComponent,
12511                    (r.intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0))
12512                            == null) {
12513                // Ah, this recipient is unavailable.  Finish it if necessary,
12514                // and mark the broadcast record as ready for the next.
12515                Log.w(TAG, "Unable to launch app "
12516                        + info.activityInfo.applicationInfo.packageName + "/"
12517                        + info.activityInfo.applicationInfo.uid + " for broadcast "
12518                        + r.intent + ": process is bad");
12519                logBroadcastReceiverDiscard(r);
12520                finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
12521                        r.resultExtras, r.resultAbort, true);
12522                scheduleBroadcastsLocked();
12523                r.state = BroadcastRecord.IDLE;
12524                return;
12525            }
12526
12527            mPendingBroadcast = r;
12528        }
12529    }
12530
12531    // =========================================================
12532    // INSTRUMENTATION
12533    // =========================================================
12534
12535    public boolean startInstrumentation(ComponentName className,
12536            String profileFile, int flags, Bundle arguments,
12537            IInstrumentationWatcher watcher) {
12538        // Refuse possible leaked file descriptors
12539        if (arguments != null && arguments.hasFileDescriptors()) {
12540            throw new IllegalArgumentException("File descriptors passed in Bundle");
12541        }
12542
12543        synchronized(this) {
12544            InstrumentationInfo ii = null;
12545            ApplicationInfo ai = null;
12546            try {
12547                ii = mContext.getPackageManager().getInstrumentationInfo(
12548                    className, STOCK_PM_FLAGS);
12549                ai = mContext.getPackageManager().getApplicationInfo(
12550                    ii.targetPackage, STOCK_PM_FLAGS);
12551            } catch (PackageManager.NameNotFoundException e) {
12552            }
12553            if (ii == null) {
12554                reportStartInstrumentationFailure(watcher, className,
12555                        "Unable to find instrumentation info for: " + className);
12556                return false;
12557            }
12558            if (ai == null) {
12559                reportStartInstrumentationFailure(watcher, className,
12560                        "Unable to find instrumentation target package: " + ii.targetPackage);
12561                return false;
12562            }
12563
12564            int match = mContext.getPackageManager().checkSignatures(
12565                    ii.targetPackage, ii.packageName);
12566            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
12567                String msg = "Permission Denial: starting instrumentation "
12568                        + className + " from pid="
12569                        + Binder.getCallingPid()
12570                        + ", uid=" + Binder.getCallingPid()
12571                        + " not allowed because package " + ii.packageName
12572                        + " does not have a signature matching the target "
12573                        + ii.targetPackage;
12574                reportStartInstrumentationFailure(watcher, className, msg);
12575                throw new SecurityException(msg);
12576            }
12577
12578            final long origId = Binder.clearCallingIdentity();
12579            uninstallPackageLocked(ii.targetPackage, -1, true);
12580            ProcessRecord app = addAppLocked(ai);
12581            app.instrumentationClass = className;
12582            app.instrumentationInfo = ai;
12583            app.instrumentationProfileFile = profileFile;
12584            app.instrumentationArguments = arguments;
12585            app.instrumentationWatcher = watcher;
12586            app.instrumentationResultClass = className;
12587            Binder.restoreCallingIdentity(origId);
12588        }
12589
12590        return true;
12591    }
12592
12593    /**
12594     * Report errors that occur while attempting to start Instrumentation.  Always writes the
12595     * error to the logs, but if somebody is watching, send the report there too.  This enables
12596     * the "am" command to report errors with more information.
12597     *
12598     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
12599     * @param cn The component name of the instrumentation.
12600     * @param report The error report.
12601     */
12602    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
12603            ComponentName cn, String report) {
12604        Log.w(TAG, report);
12605        try {
12606            if (watcher != null) {
12607                Bundle results = new Bundle();
12608                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
12609                results.putString("Error", report);
12610                watcher.instrumentationStatus(cn, -1, results);
12611            }
12612        } catch (RemoteException e) {
12613            Log.w(TAG, e);
12614        }
12615    }
12616
12617    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
12618        if (app.instrumentationWatcher != null) {
12619            try {
12620                // NOTE:  IInstrumentationWatcher *must* be oneway here
12621                app.instrumentationWatcher.instrumentationFinished(
12622                    app.instrumentationClass,
12623                    resultCode,
12624                    results);
12625            } catch (RemoteException e) {
12626            }
12627        }
12628        app.instrumentationWatcher = null;
12629        app.instrumentationClass = null;
12630        app.instrumentationInfo = null;
12631        app.instrumentationProfileFile = null;
12632        app.instrumentationArguments = null;
12633
12634        uninstallPackageLocked(app.processName, -1, false);
12635    }
12636
12637    public void finishInstrumentation(IApplicationThread target,
12638            int resultCode, Bundle results) {
12639        // Refuse possible leaked file descriptors
12640        if (results != null && results.hasFileDescriptors()) {
12641            throw new IllegalArgumentException("File descriptors passed in Intent");
12642        }
12643
12644        synchronized(this) {
12645            ProcessRecord app = getRecordForAppLocked(target);
12646            if (app == null) {
12647                Log.w(TAG, "finishInstrumentation: no app for " + target);
12648                return;
12649            }
12650            final long origId = Binder.clearCallingIdentity();
12651            finishInstrumentationLocked(app, resultCode, results);
12652            Binder.restoreCallingIdentity(origId);
12653        }
12654    }
12655
12656    // =========================================================
12657    // CONFIGURATION
12658    // =========================================================
12659
12660    public ConfigurationInfo getDeviceConfigurationInfo() {
12661        ConfigurationInfo config = new ConfigurationInfo();
12662        synchronized (this) {
12663            config.reqTouchScreen = mConfiguration.touchscreen;
12664            config.reqKeyboardType = mConfiguration.keyboard;
12665            config.reqNavigation = mConfiguration.navigation;
12666            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
12667                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
12668                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
12669            }
12670            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
12671                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
12672                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
12673            }
12674            config.reqGlEsVersion = GL_ES_VERSION;
12675        }
12676        return config;
12677    }
12678
12679    public Configuration getConfiguration() {
12680        Configuration ci;
12681        synchronized(this) {
12682            ci = new Configuration(mConfiguration);
12683        }
12684        return ci;
12685    }
12686
12687    public void updateConfiguration(Configuration values) {
12688        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
12689                "updateConfiguration()");
12690
12691        synchronized(this) {
12692            if (values == null && mWindowManager != null) {
12693                // sentinel: fetch the current configuration from the window manager
12694                values = mWindowManager.computeNewConfiguration();
12695            }
12696
12697            final long origId = Binder.clearCallingIdentity();
12698            updateConfigurationLocked(values, null);
12699            Binder.restoreCallingIdentity(origId);
12700        }
12701    }
12702
12703    /**
12704     * Do either or both things: (1) change the current configuration, and (2)
12705     * make sure the given activity is running with the (now) current
12706     * configuration.  Returns true if the activity has been left running, or
12707     * false if <var>starting</var> is being destroyed to match the new
12708     * configuration.
12709     */
12710    public boolean updateConfigurationLocked(Configuration values,
12711            HistoryRecord starting) {
12712        int changes = 0;
12713
12714        boolean kept = true;
12715
12716        if (values != null) {
12717            Configuration newConfig = new Configuration(mConfiguration);
12718            changes = newConfig.updateFrom(values);
12719            if (changes != 0) {
12720                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
12721                    Log.i(TAG, "Updating configuration to: " + values);
12722                }
12723
12724                EventLog.writeEvent(LOG_CONFIGURATION_CHANGED, changes);
12725
12726                if (values.locale != null) {
12727                    saveLocaleLocked(values.locale,
12728                                     !values.locale.equals(mConfiguration.locale),
12729                                     values.userSetLocale);
12730                }
12731
12732                mConfiguration = newConfig;
12733                Log.i(TAG, "Config changed: " + newConfig);
12734
12735                Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
12736                msg.obj = new Configuration(mConfiguration);
12737                mHandler.sendMessage(msg);
12738
12739                final int N = mLRUProcesses.size();
12740                for (int i=0; i<N; i++) {
12741                    ProcessRecord app = mLRUProcesses.get(i);
12742                    try {
12743                        if (app.thread != null) {
12744                            if (DEBUG_CONFIGURATION) Log.v(TAG, "Sending to proc "
12745                                    + app.processName + " new config " + mConfiguration);
12746                            app.thread.scheduleConfigurationChanged(mConfiguration);
12747                        }
12748                    } catch (Exception e) {
12749                    }
12750                }
12751                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
12752                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
12753                        null, false, false, MY_PID, Process.SYSTEM_UID);
12754
12755                AttributeCache ac = AttributeCache.instance();
12756                if (ac != null) {
12757                    ac.updateConfiguration(mConfiguration);
12758                }
12759            }
12760        }
12761
12762        if (changes != 0 && starting == null) {
12763            // If the configuration changed, and the caller is not already
12764            // in the process of starting an activity, then find the top
12765            // activity to check if its configuration needs to change.
12766            starting = topRunningActivityLocked(null);
12767        }
12768
12769        if (starting != null) {
12770            kept = ensureActivityConfigurationLocked(starting, changes);
12771            if (kept) {
12772                // If this didn't result in the starting activity being
12773                // destroyed, then we need to make sure at this point that all
12774                // other activities are made visible.
12775                if (DEBUG_SWITCH) Log.i(TAG, "Config didn't destroy " + starting
12776                        + ", ensuring others are correct.");
12777                ensureActivitiesVisibleLocked(starting, changes);
12778            }
12779        }
12780
12781        return kept;
12782    }
12783
12784    private final boolean relaunchActivityLocked(HistoryRecord r,
12785            int changes, boolean andResume) {
12786        List<ResultInfo> results = null;
12787        List<Intent> newIntents = null;
12788        if (andResume) {
12789            results = r.results;
12790            newIntents = r.newIntents;
12791        }
12792        if (DEBUG_SWITCH) Log.v(TAG, "Relaunching: " + r
12793                + " with results=" + results + " newIntents=" + newIntents
12794                + " andResume=" + andResume);
12795        EventLog.writeEvent(andResume ? LOG_AM_RELAUNCH_RESUME_ACTIVITY
12796                : LOG_AM_RELAUNCH_ACTIVITY, System.identityHashCode(r),
12797                r.task.taskId, r.shortComponentName);
12798
12799        r.startFreezingScreenLocked(r.app, 0);
12800
12801        try {
12802            if (DEBUG_SWITCH) Log.i(TAG, "Switch is restarting resumed " + r);
12803            r.app.thread.scheduleRelaunchActivity(r, results, newIntents,
12804                    changes, !andResume);
12805            // Note: don't need to call pauseIfSleepingLocked() here, because
12806            // the caller will only pass in 'andResume' if this activity is
12807            // currently resumed, which implies we aren't sleeping.
12808        } catch (RemoteException e) {
12809            return false;
12810        }
12811
12812        if (andResume) {
12813            r.results = null;
12814            r.newIntents = null;
12815        }
12816
12817        return true;
12818    }
12819
12820    /**
12821     * Make sure the given activity matches the current configuration.  Returns
12822     * false if the activity had to be destroyed.  Returns true if the
12823     * configuration is the same, or the activity will remain running as-is
12824     * for whatever reason.  Ensures the HistoryRecord is updated with the
12825     * correct configuration and all other bookkeeping is handled.
12826     */
12827    private final boolean ensureActivityConfigurationLocked(HistoryRecord r,
12828            int globalChanges) {
12829        if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Log.v(TAG,
12830                "Ensuring correct configuration: " + r);
12831
12832        // Short circuit: if the two configurations are the exact same
12833        // object (the common case), then there is nothing to do.
12834        Configuration newConfig = mConfiguration;
12835        if (r.configuration == newConfig) {
12836            if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Log.v(TAG,
12837                    "Configuration unchanged in " + r);
12838            return true;
12839        }
12840
12841        // We don't worry about activities that are finishing.
12842        if (r.finishing) {
12843            if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Log.v(TAG,
12844                    "Configuration doesn't matter in finishing " + r);
12845            r.stopFreezingScreenLocked(false);
12846            return true;
12847        }
12848
12849        // Okay we now are going to make this activity have the new config.
12850        // But then we need to figure out how it needs to deal with that.
12851        Configuration oldConfig = r.configuration;
12852        r.configuration = newConfig;
12853
12854        // If the activity isn't currently running, just leave the new
12855        // configuration and it will pick that up next time it starts.
12856        if (r.app == null || r.app.thread == null) {
12857            if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Log.v(TAG,
12858                    "Configuration doesn't matter not running " + r);
12859            r.stopFreezingScreenLocked(false);
12860            return true;
12861        }
12862
12863        // If the activity isn't persistent, there is a chance we will
12864        // need to restart it.
12865        if (!r.persistent) {
12866
12867            // Figure out what has changed between the two configurations.
12868            int changes = oldConfig.diff(newConfig);
12869            if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
12870                Log.v(TAG, "Checking to restart " + r.info.name + ": changed=0x"
12871                        + Integer.toHexString(changes) + ", handles=0x"
12872                        + Integer.toHexString(r.info.configChanges)
12873                        + ", newConfig=" + newConfig);
12874            }
12875            if ((changes&(~r.info.configChanges)) != 0) {
12876                // Aha, the activity isn't handling the change, so DIE DIE DIE.
12877                r.configChangeFlags |= changes;
12878                r.startFreezingScreenLocked(r.app, globalChanges);
12879                if (r.app == null || r.app.thread == null) {
12880                    if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Log.v(TAG,
12881                            "Switch is destroying non-running " + r);
12882                    destroyActivityLocked(r, true);
12883                } else if (r.state == ActivityState.PAUSING) {
12884                    // A little annoying: we are waiting for this activity to
12885                    // finish pausing.  Let's not do anything now, but just
12886                    // flag that it needs to be restarted when done pausing.
12887                    if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Log.v(TAG,
12888                            "Switch is skipping already pausing " + r);
12889                    r.configDestroy = true;
12890                    return true;
12891                } else if (r.state == ActivityState.RESUMED) {
12892                    // Try to optimize this case: the configuration is changing
12893                    // and we need to restart the top, resumed activity.
12894                    // Instead of doing the normal handshaking, just say
12895                    // "restart!".
12896                    if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Log.v(TAG,
12897                            "Switch is restarting resumed " + r);
12898                    relaunchActivityLocked(r, r.configChangeFlags, true);
12899                    r.configChangeFlags = 0;
12900                } else {
12901                    if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Log.v(TAG,
12902                            "Switch is restarting non-resumed " + r);
12903                    relaunchActivityLocked(r, r.configChangeFlags, false);
12904                    r.configChangeFlags = 0;
12905                }
12906
12907                // All done...  tell the caller we weren't able to keep this
12908                // activity around.
12909                return false;
12910            }
12911        }
12912
12913        // Default case: the activity can handle this new configuration, so
12914        // hand it over.  Note that we don't need to give it the new
12915        // configuration, since we always send configuration changes to all
12916        // process when they happen so it can just use whatever configuration
12917        // it last got.
12918        if (r.app != null && r.app.thread != null) {
12919            try {
12920                if (DEBUG_CONFIGURATION) Log.v(TAG, "Sending new config to " + r);
12921                r.app.thread.scheduleActivityConfigurationChanged(r);
12922            } catch (RemoteException e) {
12923                // If process died, whatever.
12924            }
12925        }
12926        r.stopFreezingScreenLocked(false);
12927
12928        return true;
12929    }
12930
12931    /**
12932     * Save the locale.  You must be inside a synchronized (this) block.
12933     */
12934    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
12935        if(isDiff) {
12936            SystemProperties.set("user.language", l.getLanguage());
12937            SystemProperties.set("user.region", l.getCountry());
12938        }
12939
12940        if(isPersist) {
12941            SystemProperties.set("persist.sys.language", l.getLanguage());
12942            SystemProperties.set("persist.sys.country", l.getCountry());
12943            SystemProperties.set("persist.sys.localevar", l.getVariant());
12944        }
12945    }
12946
12947    // =========================================================
12948    // LIFETIME MANAGEMENT
12949    // =========================================================
12950
12951    private final int computeOomAdjLocked(
12952        ProcessRecord app, int hiddenAdj, ProcessRecord TOP_APP) {
12953        if (mAdjSeq == app.adjSeq) {
12954            // This adjustment has already been computed.
12955            return app.curAdj;
12956        }
12957
12958        if (app.thread == null) {
12959            app.adjSeq = mAdjSeq;
12960            return (app.curAdj=EMPTY_APP_ADJ);
12961        }
12962
12963        if (app.maxAdj <= FOREGROUND_APP_ADJ) {
12964            // The max adjustment doesn't allow this app to be anything
12965            // below foreground, so it is not worth doing work for it.
12966            app.adjType = "fixed";
12967            app.adjSeq = mAdjSeq;
12968            app.curRawAdj = app.maxAdj;
12969            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
12970            return (app.curAdj=app.maxAdj);
12971       }
12972
12973        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
12974        app.adjSource = null;
12975        app.adjTarget = null;
12976
12977        // Determine the importance of the process, starting with most
12978        // important to least, and assign an appropriate OOM adjustment.
12979        int adj;
12980        int N;
12981        if (app == TOP_APP) {
12982            // The last app on the list is the foreground app.
12983            adj = FOREGROUND_APP_ADJ;
12984            app.adjType = "top-activity";
12985        } else if (app.instrumentationClass != null) {
12986            // Don't want to kill running instrumentation.
12987            adj = FOREGROUND_APP_ADJ;
12988            app.adjType = "instrumentation";
12989        } else if (app.persistentActivities > 0) {
12990            // Special persistent activities...  shouldn't be used these days.
12991            adj = FOREGROUND_APP_ADJ;
12992            app.adjType = "persistent";
12993        } else if (app.curReceiver != null ||
12994                (mPendingBroadcast != null && mPendingBroadcast.curApp == app)) {
12995            // An app that is currently receiving a broadcast also
12996            // counts as being in the foreground.
12997            adj = FOREGROUND_APP_ADJ;
12998            app.adjType = "broadcast";
12999        } else if (app.executingServices.size() > 0) {
13000            // An app that is currently executing a service callback also
13001            // counts as being in the foreground.
13002            adj = FOREGROUND_APP_ADJ;
13003            app.adjType = "exec-service";
13004        } else if (app.foregroundServices) {
13005            // The user is aware of this app, so make it visible.
13006            adj = VISIBLE_APP_ADJ;
13007            app.adjType = "foreground-service";
13008        } else if (app.forcingToForeground != null) {
13009            // The user is aware of this app, so make it visible.
13010            adj = VISIBLE_APP_ADJ;
13011            app.adjType = "force-foreground";
13012            app.adjSource = app.forcingToForeground;
13013        } else if (app == mHomeProcess) {
13014            // This process is hosting what we currently consider to be the
13015            // home app, so we don't want to let it go into the background.
13016            adj = HOME_APP_ADJ;
13017            app.adjType = "home";
13018        } else if ((N=app.activities.size()) != 0) {
13019            // This app is in the background with paused activities.
13020            adj = hiddenAdj;
13021            app.adjType = "bg-activities";
13022            for (int j=0; j<N; j++) {
13023                if (((HistoryRecord)app.activities.get(j)).visible) {
13024                    // This app has a visible activity!
13025                    adj = VISIBLE_APP_ADJ;
13026                    app.adjType = "visible";
13027                    break;
13028                }
13029            }
13030        } else {
13031            // A very not-needed process.
13032            adj = EMPTY_APP_ADJ;
13033            app.adjType = "empty";
13034        }
13035
13036        // By default, we use the computed adjustment.  It may be changed if
13037        // there are applications dependent on our services or providers, but
13038        // this gives us a baseline and makes sure we don't get into an
13039        // infinite recursion.
13040        app.adjSeq = mAdjSeq;
13041        app.curRawAdj = adj;
13042        app.curAdj = adj <= app.maxAdj ? adj : app.maxAdj;
13043
13044        if (mBackupTarget != null && app == mBackupTarget.app) {
13045            // If possible we want to avoid killing apps while they're being backed up
13046            if (adj > BACKUP_APP_ADJ) {
13047                if (DEBUG_BACKUP) Log.v(TAG, "oom BACKUP_APP_ADJ for " + app);
13048                adj = BACKUP_APP_ADJ;
13049                app.adjType = "backup";
13050            }
13051        }
13052
13053        if (app.services.size() != 0 && adj > FOREGROUND_APP_ADJ) {
13054            final long now = SystemClock.uptimeMillis();
13055            // This process is more important if the top activity is
13056            // bound to the service.
13057            Iterator jt = app.services.iterator();
13058            while (jt.hasNext() && adj > FOREGROUND_APP_ADJ) {
13059                ServiceRecord s = (ServiceRecord)jt.next();
13060                if (s.startRequested) {
13061                    if (now < (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
13062                        // This service has seen some activity within
13063                        // recent memory, so we will keep its process ahead
13064                        // of the background processes.
13065                        if (adj > SECONDARY_SERVER_ADJ) {
13066                            adj = SECONDARY_SERVER_ADJ;
13067                            app.adjType = "started-services";
13068                        }
13069                    }
13070                }
13071                if (s.connections.size() > 0 && adj > FOREGROUND_APP_ADJ) {
13072                    Iterator<ConnectionRecord> kt
13073                            = s.connections.values().iterator();
13074                    while (kt.hasNext() && adj > FOREGROUND_APP_ADJ) {
13075                        // XXX should compute this based on the max of
13076                        // all connected clients.
13077                        ConnectionRecord cr = kt.next();
13078                        if (cr.binding.client == app) {
13079                            // Binding to ourself is not interesting.
13080                            continue;
13081                        }
13082                        if ((cr.flags&Context.BIND_AUTO_CREATE) != 0) {
13083                            ProcessRecord client = cr.binding.client;
13084                            int myHiddenAdj = hiddenAdj;
13085                            if (myHiddenAdj > client.hiddenAdj) {
13086                                if (client.hiddenAdj > VISIBLE_APP_ADJ) {
13087                                    myHiddenAdj = client.hiddenAdj;
13088                                } else {
13089                                    myHiddenAdj = VISIBLE_APP_ADJ;
13090                                }
13091                            }
13092                            int clientAdj = computeOomAdjLocked(
13093                                client, myHiddenAdj, TOP_APP);
13094                            if (adj > clientAdj) {
13095                                adj = clientAdj > VISIBLE_APP_ADJ
13096                                        ? clientAdj : VISIBLE_APP_ADJ;
13097                                app.adjType = "service";
13098                                app.adjTypeCode = ActivityManager.RunningAppProcessInfo
13099                                        .REASON_SERVICE_IN_USE;
13100                                app.adjSource = cr.binding.client;
13101                                app.adjTarget = s.serviceInfo.name;
13102                            }
13103                        }
13104                        HistoryRecord a = cr.activity;
13105                        //if (a != null) {
13106                        //    Log.i(TAG, "Connection to " + a ": state=" + a.state);
13107                        //}
13108                        if (a != null && adj > FOREGROUND_APP_ADJ &&
13109                                (a.state == ActivityState.RESUMED
13110                                 || a.state == ActivityState.PAUSING)) {
13111                            adj = FOREGROUND_APP_ADJ;
13112                            app.adjType = "service";
13113                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
13114                                    .REASON_SERVICE_IN_USE;
13115                            app.adjSource = a;
13116                            app.adjTarget = s.serviceInfo.name;
13117                        }
13118                    }
13119                }
13120            }
13121
13122            // Finally, f this process has active services running in it, we
13123            // would like to avoid killing it unless it would prevent the current
13124            // application from running.  By default we put the process in
13125            // with the rest of the background processes; as we scan through
13126            // its services we may bump it up from there.
13127            if (adj > hiddenAdj) {
13128                adj = hiddenAdj;
13129                app.adjType = "bg-services";
13130            }
13131        }
13132
13133        if (app.pubProviders.size() != 0 && adj > FOREGROUND_APP_ADJ) {
13134            Iterator jt = app.pubProviders.values().iterator();
13135            while (jt.hasNext() && adj > FOREGROUND_APP_ADJ) {
13136                ContentProviderRecord cpr = (ContentProviderRecord)jt.next();
13137                if (cpr.clients.size() != 0) {
13138                    Iterator<ProcessRecord> kt = cpr.clients.iterator();
13139                    while (kt.hasNext() && adj > FOREGROUND_APP_ADJ) {
13140                        ProcessRecord client = kt.next();
13141                        if (client == app) {
13142                            // Being our own client is not interesting.
13143                            continue;
13144                        }
13145                        int myHiddenAdj = hiddenAdj;
13146                        if (myHiddenAdj > client.hiddenAdj) {
13147                            if (client.hiddenAdj > FOREGROUND_APP_ADJ) {
13148                                myHiddenAdj = client.hiddenAdj;
13149                            } else {
13150                                myHiddenAdj = FOREGROUND_APP_ADJ;
13151                            }
13152                        }
13153                        int clientAdj = computeOomAdjLocked(
13154                            client, myHiddenAdj, TOP_APP);
13155                        if (adj > clientAdj) {
13156                            adj = clientAdj > FOREGROUND_APP_ADJ
13157                                    ? clientAdj : FOREGROUND_APP_ADJ;
13158                            app.adjType = "provider";
13159                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
13160                                    .REASON_PROVIDER_IN_USE;
13161                            app.adjSource = client;
13162                            app.adjTarget = cpr.info.name;
13163                        }
13164                    }
13165                }
13166                // If the provider has external (non-framework) process
13167                // dependencies, ensure that its adjustment is at least
13168                // FOREGROUND_APP_ADJ.
13169                if (cpr.externals != 0) {
13170                    if (adj > FOREGROUND_APP_ADJ) {
13171                        adj = FOREGROUND_APP_ADJ;
13172                        app.adjType = "provider";
13173                        app.adjTarget = cpr.info.name;
13174                    }
13175                }
13176            }
13177
13178            // Finally, if this process has published any content providers,
13179            // then its adjustment makes it at least as important as any of the
13180            // processes using those providers, and no less important than
13181            // CONTENT_PROVIDER_ADJ, which is just shy of EMPTY.
13182            if (adj > CONTENT_PROVIDER_ADJ) {
13183                adj = CONTENT_PROVIDER_ADJ;
13184                app.adjType = "pub-providers";
13185            }
13186        }
13187
13188        app.curRawAdj = adj;
13189
13190        //Log.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
13191        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
13192        if (adj > app.maxAdj) {
13193            adj = app.maxAdj;
13194        }
13195
13196        app.curAdj = adj;
13197        app.curSchedGroup = adj > VISIBLE_APP_ADJ
13198                ? Process.THREAD_GROUP_BG_NONINTERACTIVE
13199                : Process.THREAD_GROUP_DEFAULT;
13200
13201        return adj;
13202    }
13203
13204    /**
13205     * Ask a given process to GC right now.
13206     */
13207    final void performAppGcLocked(ProcessRecord app) {
13208        try {
13209            app.lastRequestedGc = SystemClock.uptimeMillis();
13210            if (app.thread != null) {
13211                if (app.reportLowMemory) {
13212                    app.reportLowMemory = false;
13213                    app.thread.scheduleLowMemory();
13214                } else {
13215                    app.thread.processInBackground();
13216                }
13217            }
13218        } catch (Exception e) {
13219            // whatever.
13220        }
13221    }
13222
13223    /**
13224     * Returns true if things are idle enough to perform GCs.
13225     */
13226    private final boolean canGcNow() {
13227        return mParallelBroadcasts.size() == 0
13228                && mOrderedBroadcasts.size() == 0
13229                && (mSleeping || (mResumedActivity != null &&
13230                        mResumedActivity.idle));
13231    }
13232
13233    /**
13234     * Perform GCs on all processes that are waiting for it, but only
13235     * if things are idle.
13236     */
13237    final void performAppGcsLocked() {
13238        final int N = mProcessesToGc.size();
13239        if (N <= 0) {
13240            return;
13241        }
13242        if (canGcNow()) {
13243            while (mProcessesToGc.size() > 0) {
13244                ProcessRecord proc = mProcessesToGc.remove(0);
13245                if (proc.curRawAdj > VISIBLE_APP_ADJ || proc.reportLowMemory) {
13246                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
13247                            <= SystemClock.uptimeMillis()) {
13248                        // To avoid spamming the system, we will GC processes one
13249                        // at a time, waiting a few seconds between each.
13250                        performAppGcLocked(proc);
13251                        scheduleAppGcsLocked();
13252                        return;
13253                    } else {
13254                        // It hasn't been long enough since we last GCed this
13255                        // process...  put it in the list to wait for its time.
13256                        addProcessToGcListLocked(proc);
13257                        break;
13258                    }
13259                }
13260            }
13261
13262            scheduleAppGcsLocked();
13263        }
13264    }
13265
13266    /**
13267     * If all looks good, perform GCs on all processes waiting for them.
13268     */
13269    final void performAppGcsIfAppropriateLocked() {
13270        if (canGcNow()) {
13271            performAppGcsLocked();
13272            return;
13273        }
13274        // Still not idle, wait some more.
13275        scheduleAppGcsLocked();
13276    }
13277
13278    /**
13279     * Schedule the execution of all pending app GCs.
13280     */
13281    final void scheduleAppGcsLocked() {
13282        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
13283
13284        if (mProcessesToGc.size() > 0) {
13285            // Schedule a GC for the time to the next process.
13286            ProcessRecord proc = mProcessesToGc.get(0);
13287            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
13288
13289            long when = mProcessesToGc.get(0).lastRequestedGc + GC_MIN_INTERVAL;
13290            long now = SystemClock.uptimeMillis();
13291            if (when < (now+GC_TIMEOUT)) {
13292                when = now + GC_TIMEOUT;
13293            }
13294            mHandler.sendMessageAtTime(msg, when);
13295        }
13296    }
13297
13298    /**
13299     * Add a process to the array of processes waiting to be GCed.  Keeps the
13300     * list in sorted order by the last GC time.  The process can't already be
13301     * on the list.
13302     */
13303    final void addProcessToGcListLocked(ProcessRecord proc) {
13304        boolean added = false;
13305        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
13306            if (mProcessesToGc.get(i).lastRequestedGc <
13307                    proc.lastRequestedGc) {
13308                added = true;
13309                mProcessesToGc.add(i+1, proc);
13310                break;
13311            }
13312        }
13313        if (!added) {
13314            mProcessesToGc.add(0, proc);
13315        }
13316    }
13317
13318    /**
13319     * Set up to ask a process to GC itself.  This will either do it
13320     * immediately, or put it on the list of processes to gc the next
13321     * time things are idle.
13322     */
13323    final void scheduleAppGcLocked(ProcessRecord app) {
13324        long now = SystemClock.uptimeMillis();
13325        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
13326            return;
13327        }
13328        if (!mProcessesToGc.contains(app)) {
13329            addProcessToGcListLocked(app);
13330            scheduleAppGcsLocked();
13331        }
13332    }
13333
13334    private final boolean updateOomAdjLocked(
13335        ProcessRecord app, int hiddenAdj, ProcessRecord TOP_APP) {
13336        app.hiddenAdj = hiddenAdj;
13337
13338        if (app.thread == null) {
13339            return true;
13340        }
13341
13342        int adj = computeOomAdjLocked(app, hiddenAdj, TOP_APP);
13343
13344        if (app.pid != 0 && app.pid != MY_PID) {
13345            if (app.curRawAdj != app.setRawAdj) {
13346                if (app.curRawAdj > FOREGROUND_APP_ADJ
13347                        && app.setRawAdj <= FOREGROUND_APP_ADJ) {
13348                    // If this app is transitioning from foreground to
13349                    // non-foreground, have it do a gc.
13350                    scheduleAppGcLocked(app);
13351                } else if (app.curRawAdj >= HIDDEN_APP_MIN_ADJ
13352                        && app.setRawAdj < HIDDEN_APP_MIN_ADJ) {
13353                    // Likewise do a gc when an app is moving in to the
13354                    // background (such as a service stopping).
13355                    scheduleAppGcLocked(app);
13356                }
13357                app.setRawAdj = app.curRawAdj;
13358            }
13359            if (adj != app.setAdj) {
13360                if (Process.setOomAdj(app.pid, adj)) {
13361                    if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Log.v(
13362                        TAG, "Set app " + app.processName +
13363                        " oom adj to " + adj);
13364                    app.setAdj = adj;
13365                } else {
13366                    return false;
13367                }
13368            }
13369            if (app.setSchedGroup != app.curSchedGroup) {
13370                app.setSchedGroup = app.curSchedGroup;
13371                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Log.v(TAG,
13372                        "Setting process group of " + app.processName
13373                        + " to " + app.curSchedGroup);
13374                if (true) {
13375                    long oldId = Binder.clearCallingIdentity();
13376                    try {
13377                        Process.setProcessGroup(app.pid, app.curSchedGroup);
13378                    } catch (Exception e) {
13379                        Log.w(TAG, "Failed setting process group of " + app.pid
13380                                + " to " + app.curSchedGroup);
13381                        e.printStackTrace();
13382                    } finally {
13383                        Binder.restoreCallingIdentity(oldId);
13384                    }
13385                }
13386                if (false) {
13387                    if (app.thread != null) {
13388                        try {
13389                            app.thread.setSchedulingGroup(app.curSchedGroup);
13390                        } catch (RemoteException e) {
13391                        }
13392                    }
13393                }
13394            }
13395        }
13396
13397        return true;
13398    }
13399
13400    private final HistoryRecord resumedAppLocked() {
13401        HistoryRecord resumedActivity = mResumedActivity;
13402        if (resumedActivity == null || resumedActivity.app == null) {
13403            resumedActivity = mPausingActivity;
13404            if (resumedActivity == null || resumedActivity.app == null) {
13405                resumedActivity = topRunningActivityLocked(null);
13406            }
13407        }
13408        return resumedActivity;
13409    }
13410
13411    private final boolean updateOomAdjLocked(ProcessRecord app) {
13412        final HistoryRecord TOP_ACT = resumedAppLocked();
13413        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13414        int curAdj = app.curAdj;
13415        final boolean wasHidden = app.curAdj >= HIDDEN_APP_MIN_ADJ
13416            && app.curAdj <= HIDDEN_APP_MAX_ADJ;
13417
13418        mAdjSeq++;
13419
13420        final boolean res = updateOomAdjLocked(app, app.hiddenAdj, TOP_APP);
13421        if (res) {
13422            final boolean nowHidden = app.curAdj >= HIDDEN_APP_MIN_ADJ
13423                && app.curAdj <= HIDDEN_APP_MAX_ADJ;
13424            if (nowHidden != wasHidden) {
13425                // Changed to/from hidden state, so apps after it in the LRU
13426                // list may also be changed.
13427                updateOomAdjLocked();
13428            }
13429        }
13430        return res;
13431    }
13432
13433    private final boolean updateOomAdjLocked() {
13434        boolean didOomAdj = true;
13435        final HistoryRecord TOP_ACT = resumedAppLocked();
13436        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13437
13438        if (false) {
13439            RuntimeException e = new RuntimeException();
13440            e.fillInStackTrace();
13441            Log.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
13442        }
13443
13444        mAdjSeq++;
13445
13446        // First try updating the OOM adjustment for each of the
13447        // application processes based on their current state.
13448        int i = mLRUProcesses.size();
13449        int curHiddenAdj = HIDDEN_APP_MIN_ADJ;
13450        while (i > 0) {
13451            i--;
13452            ProcessRecord app = mLRUProcesses.get(i);
13453            if (updateOomAdjLocked(app, curHiddenAdj, TOP_APP)) {
13454                if (curHiddenAdj < HIDDEN_APP_MAX_ADJ
13455                    && app.curAdj == curHiddenAdj) {
13456                    curHiddenAdj++;
13457                }
13458            } else {
13459                didOomAdj = false;
13460            }
13461        }
13462
13463        // todo: for now pretend like OOM ADJ didn't work, because things
13464        // aren't behaving as expected on Linux -- it's not killing processes.
13465        return ENFORCE_PROCESS_LIMIT || mProcessLimit > 0 ? false : didOomAdj;
13466    }
13467
13468    private final void trimApplications() {
13469        synchronized (this) {
13470            int i;
13471
13472            // First remove any unused application processes whose package
13473            // has been removed.
13474            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
13475                final ProcessRecord app = mRemovedProcesses.get(i);
13476                if (app.activities.size() == 0
13477                        && app.curReceiver == null && app.services.size() == 0) {
13478                    Log.i(
13479                        TAG, "Exiting empty application process "
13480                        + app.processName + " ("
13481                        + (app.thread != null ? app.thread.asBinder() : null)
13482                        + ")\n");
13483                    if (app.pid > 0 && app.pid != MY_PID) {
13484                        Process.killProcess(app.pid);
13485                    } else {
13486                        try {
13487                            app.thread.scheduleExit();
13488                        } catch (Exception e) {
13489                            // Ignore exceptions.
13490                        }
13491                    }
13492                    cleanUpApplicationRecordLocked(app, false, -1);
13493                    mRemovedProcesses.remove(i);
13494
13495                    if (app.persistent) {
13496                        if (app.persistent) {
13497                            addAppLocked(app.info);
13498                        }
13499                    }
13500                }
13501            }
13502
13503            // Now try updating the OOM adjustment for each of the
13504            // application processes based on their current state.
13505            // If the setOomAdj() API is not supported, then go with our
13506            // back-up plan...
13507            if (!updateOomAdjLocked()) {
13508
13509                // Count how many processes are running services.
13510                int numServiceProcs = 0;
13511                for (i=mLRUProcesses.size()-1; i>=0; i--) {
13512                    final ProcessRecord app = mLRUProcesses.get(i);
13513
13514                    if (app.persistent || app.services.size() != 0
13515                            || app.curReceiver != null
13516                            || app.persistentActivities > 0) {
13517                        // Don't count processes holding services against our
13518                        // maximum process count.
13519                        if (localLOGV) Log.v(
13520                            TAG, "Not trimming app " + app + " with services: "
13521                            + app.services);
13522                        numServiceProcs++;
13523                    }
13524                }
13525
13526                int curMaxProcs = mProcessLimit;
13527                if (curMaxProcs <= 0) curMaxProcs = MAX_PROCESSES;
13528                if (mAlwaysFinishActivities) {
13529                    curMaxProcs = 1;
13530                }
13531                curMaxProcs += numServiceProcs;
13532
13533                // Quit as many processes as we can to get down to the desired
13534                // process count.  First remove any processes that no longer
13535                // have activites running in them.
13536                for (   i=0;
13537                        i<mLRUProcesses.size()
13538                            && mLRUProcesses.size() > curMaxProcs;
13539                        i++) {
13540                    final ProcessRecord app = mLRUProcesses.get(i);
13541                    // Quit an application only if it is not currently
13542                    // running any activities.
13543                    if (!app.persistent && app.activities.size() == 0
13544                            && app.curReceiver == null && app.services.size() == 0) {
13545                        Log.i(
13546                            TAG, "Exiting empty application process "
13547                            + app.processName + " ("
13548                            + (app.thread != null ? app.thread.asBinder() : null)
13549                            + ")\n");
13550                        if (app.pid > 0 && app.pid != MY_PID) {
13551                            Process.killProcess(app.pid);
13552                        } else {
13553                            try {
13554                                app.thread.scheduleExit();
13555                            } catch (Exception e) {
13556                                // Ignore exceptions.
13557                            }
13558                        }
13559                        // todo: For now we assume the application is not buggy
13560                        // or evil, and will quit as a result of our request.
13561                        // Eventually we need to drive this off of the death
13562                        // notification, and kill the process if it takes too long.
13563                        cleanUpApplicationRecordLocked(app, false, i);
13564                        i--;
13565                    }
13566                }
13567
13568                // If we still have too many processes, now from the least
13569                // recently used process we start finishing activities.
13570                if (Config.LOGV) Log.v(
13571                    TAG, "*** NOW HAVE " + mLRUProcesses.size() +
13572                    " of " + curMaxProcs + " processes");
13573                for (   i=0;
13574                        i<mLRUProcesses.size()
13575                            && mLRUProcesses.size() > curMaxProcs;
13576                        i++) {
13577                    final ProcessRecord app = mLRUProcesses.get(i);
13578                    // Quit the application only if we have a state saved for
13579                    // all of its activities.
13580                    boolean canQuit = !app.persistent && app.curReceiver == null
13581                        && app.services.size() == 0
13582                        && app.persistentActivities == 0;
13583                    int NUMA = app.activities.size();
13584                    int j;
13585                    if (Config.LOGV) Log.v(
13586                        TAG, "Looking to quit " + app.processName);
13587                    for (j=0; j<NUMA && canQuit; j++) {
13588                        HistoryRecord r = (HistoryRecord)app.activities.get(j);
13589                        if (Config.LOGV) Log.v(
13590                            TAG, "  " + r.intent.getComponent().flattenToShortString()
13591                            + ": frozen=" + r.haveState + ", visible=" + r.visible);
13592                        canQuit = (r.haveState || !r.stateNotNeeded)
13593                                && !r.visible && r.stopped;
13594                    }
13595                    if (canQuit) {
13596                        // Finish all of the activities, and then the app itself.
13597                        for (j=0; j<NUMA; j++) {
13598                            HistoryRecord r = (HistoryRecord)app.activities.get(j);
13599                            if (!r.finishing) {
13600                                destroyActivityLocked(r, false);
13601                            }
13602                            r.resultTo = null;
13603                        }
13604                        Log.i(TAG, "Exiting application process "
13605                              + app.processName + " ("
13606                              + (app.thread != null ? app.thread.asBinder() : null)
13607                              + ")\n");
13608                        if (app.pid > 0 && app.pid != MY_PID) {
13609                            Process.killProcess(app.pid);
13610                        } else {
13611                            try {
13612                                app.thread.scheduleExit();
13613                            } catch (Exception e) {
13614                                // Ignore exceptions.
13615                            }
13616                        }
13617                        // todo: For now we assume the application is not buggy
13618                        // or evil, and will quit as a result of our request.
13619                        // Eventually we need to drive this off of the death
13620                        // notification, and kill the process if it takes too long.
13621                        cleanUpApplicationRecordLocked(app, false, i);
13622                        i--;
13623                        //dump();
13624                    }
13625                }
13626
13627            }
13628
13629            int curMaxActivities = MAX_ACTIVITIES;
13630            if (mAlwaysFinishActivities) {
13631                curMaxActivities = 1;
13632            }
13633
13634            // Finally, if there are too many activities now running, try to
13635            // finish as many as we can to get back down to the limit.
13636            for (   i=0;
13637                    i<mLRUActivities.size()
13638                        && mLRUActivities.size() > curMaxActivities;
13639                    i++) {
13640                final HistoryRecord r
13641                    = (HistoryRecord)mLRUActivities.get(i);
13642
13643                // We can finish this one if we have its icicle saved and
13644                // it is not persistent.
13645                if ((r.haveState || !r.stateNotNeeded) && !r.visible
13646                        && r.stopped && !r.persistent && !r.finishing) {
13647                    final int origSize = mLRUActivities.size();
13648                    destroyActivityLocked(r, true);
13649
13650                    // This will remove it from the LRU list, so keep
13651                    // our index at the same value.  Note that this check to
13652                    // see if the size changes is just paranoia -- if
13653                    // something unexpected happens, we don't want to end up
13654                    // in an infinite loop.
13655                    if (origSize > mLRUActivities.size()) {
13656                        i--;
13657                    }
13658                }
13659            }
13660        }
13661    }
13662
13663    /** This method sends the specified signal to each of the persistent apps */
13664    public void signalPersistentProcesses(int sig) throws RemoteException {
13665        if (sig != Process.SIGNAL_USR1) {
13666            throw new SecurityException("Only SIGNAL_USR1 is allowed");
13667        }
13668
13669        synchronized (this) {
13670            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
13671                    != PackageManager.PERMISSION_GRANTED) {
13672                throw new SecurityException("Requires permission "
13673                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
13674            }
13675
13676            for (int i = mLRUProcesses.size() - 1 ; i >= 0 ; i--) {
13677                ProcessRecord r = mLRUProcesses.get(i);
13678                if (r.thread != null && r.persistent) {
13679                    Process.sendSignal(r.pid, sig);
13680                }
13681            }
13682        }
13683    }
13684
13685    public boolean profileControl(String process, boolean start,
13686            String path, ParcelFileDescriptor fd) throws RemoteException {
13687
13688        try {
13689            synchronized (this) {
13690                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13691                // its own permission.
13692                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13693                        != PackageManager.PERMISSION_GRANTED) {
13694                    throw new SecurityException("Requires permission "
13695                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13696                }
13697
13698                if (start && fd == null) {
13699                    throw new IllegalArgumentException("null fd");
13700                }
13701
13702                ProcessRecord proc = null;
13703                try {
13704                    int pid = Integer.parseInt(process);
13705                    synchronized (mPidsSelfLocked) {
13706                        proc = mPidsSelfLocked.get(pid);
13707                    }
13708                } catch (NumberFormatException e) {
13709                }
13710
13711                if (proc == null) {
13712                    HashMap<String, SparseArray<ProcessRecord>> all
13713                            = mProcessNames.getMap();
13714                    SparseArray<ProcessRecord> procs = all.get(process);
13715                    if (procs != null && procs.size() > 0) {
13716                        proc = procs.valueAt(0);
13717                    }
13718                }
13719
13720                if (proc == null || proc.thread == null) {
13721                    throw new IllegalArgumentException("Unknown process: " + process);
13722                }
13723
13724                boolean isSecure = "1".equals(SystemProperties.get(SYSTEM_SECURE, "0"));
13725                if (isSecure) {
13726                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
13727                        throw new SecurityException("Process not debuggable: " + proc);
13728                    }
13729                }
13730
13731                proc.thread.profilerControl(start, path, fd);
13732                fd = null;
13733                return true;
13734            }
13735        } catch (RemoteException e) {
13736            throw new IllegalStateException("Process disappeared");
13737        } finally {
13738            if (fd != null) {
13739                try {
13740                    fd.close();
13741                } catch (IOException e) {
13742                }
13743            }
13744        }
13745    }
13746
13747    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
13748    public void monitor() {
13749        synchronized (this) { }
13750    }
13751}
13752