ActivityManagerService.java revision c9568e3989f1491abaa7960eca986af12743cb05
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 || false;
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, null);
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, null);
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        Log.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
1440
1441        MY_PID = Process.myPid();
1442
1443        File dataDir = Environment.getDataDirectory();
1444        File systemDir = new File(dataDir, "system");
1445        systemDir.mkdirs();
1446        mBatteryStatsService = new BatteryStatsService(new File(
1447                systemDir, "batterystats.bin").toString());
1448        mBatteryStatsService.getActiveStatistics().readLocked();
1449        mBatteryStatsService.getActiveStatistics().writeLocked();
1450
1451        mUsageStatsService = new UsageStatsService( new File(
1452                systemDir, "usagestats").toString());
1453
1454        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
1455            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
1456
1457        mConfiguration.makeDefault();
1458        mProcessStats.init();
1459
1460        // Add ourself to the Watchdog monitors.
1461        Watchdog.getInstance().addMonitor(this);
1462
1463        // These values are set in system/rootdir/init.rc on startup.
1464        FOREGROUND_APP_ADJ =
1465            Integer.valueOf(SystemProperties.get("ro.FOREGROUND_APP_ADJ"));
1466        VISIBLE_APP_ADJ =
1467            Integer.valueOf(SystemProperties.get("ro.VISIBLE_APP_ADJ"));
1468        SECONDARY_SERVER_ADJ =
1469            Integer.valueOf(SystemProperties.get("ro.SECONDARY_SERVER_ADJ"));
1470        BACKUP_APP_ADJ =
1471            Integer.valueOf(SystemProperties.get("ro.BACKUP_APP_ADJ"));
1472        HOME_APP_ADJ =
1473            Integer.valueOf(SystemProperties.get("ro.HOME_APP_ADJ"));
1474        HIDDEN_APP_MIN_ADJ =
1475            Integer.valueOf(SystemProperties.get("ro.HIDDEN_APP_MIN_ADJ"));
1476        CONTENT_PROVIDER_ADJ =
1477            Integer.valueOf(SystemProperties.get("ro.CONTENT_PROVIDER_ADJ"));
1478        HIDDEN_APP_MAX_ADJ = CONTENT_PROVIDER_ADJ-1;
1479        EMPTY_APP_ADJ =
1480            Integer.valueOf(SystemProperties.get("ro.EMPTY_APP_ADJ"));
1481        FOREGROUND_APP_MEM =
1482            Integer.valueOf(SystemProperties.get("ro.FOREGROUND_APP_MEM"))*PAGE_SIZE;
1483        VISIBLE_APP_MEM =
1484            Integer.valueOf(SystemProperties.get("ro.VISIBLE_APP_MEM"))*PAGE_SIZE;
1485        SECONDARY_SERVER_MEM =
1486            Integer.valueOf(SystemProperties.get("ro.SECONDARY_SERVER_MEM"))*PAGE_SIZE;
1487        BACKUP_APP_MEM =
1488            Integer.valueOf(SystemProperties.get("ro.BACKUP_APP_MEM"))*PAGE_SIZE;
1489        HOME_APP_MEM =
1490            Integer.valueOf(SystemProperties.get("ro.HOME_APP_MEM"))*PAGE_SIZE;
1491        HIDDEN_APP_MEM =
1492            Integer.valueOf(SystemProperties.get("ro.HIDDEN_APP_MEM"))*PAGE_SIZE;
1493        EMPTY_APP_MEM =
1494            Integer.valueOf(SystemProperties.get("ro.EMPTY_APP_MEM"))*PAGE_SIZE;
1495
1496        mProcessStatsThread = new Thread("ProcessStats") {
1497            public void run() {
1498                while (true) {
1499                    try {
1500                        try {
1501                            synchronized(this) {
1502                                final long now = SystemClock.uptimeMillis();
1503                                long nextCpuDelay = (mLastCpuTime+MONITOR_CPU_MAX_TIME)-now;
1504                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
1505                                //Log.i(TAG, "Cpu delay=" + nextCpuDelay
1506                                //        + ", write delay=" + nextWriteDelay);
1507                                if (nextWriteDelay < nextCpuDelay) {
1508                                    nextCpuDelay = nextWriteDelay;
1509                                }
1510                                if (nextCpuDelay > 0) {
1511                                    this.wait(nextCpuDelay);
1512                                }
1513                            }
1514                        } catch (InterruptedException e) {
1515                        }
1516
1517                        updateCpuStatsNow();
1518                    } catch (Exception e) {
1519                        Log.e(TAG, "Unexpected exception collecting process stats", e);
1520                    }
1521                }
1522            }
1523        };
1524        mProcessStatsThread.start();
1525    }
1526
1527    @Override
1528    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
1529            throws RemoteException {
1530        try {
1531            return super.onTransact(code, data, reply, flags);
1532        } catch (RuntimeException e) {
1533            // The activity manager only throws security exceptions, so let's
1534            // log all others.
1535            if (!(e instanceof SecurityException)) {
1536                Log.e(TAG, "Activity Manager Crash", e);
1537            }
1538            throw e;
1539        }
1540    }
1541
1542    void updateCpuStats() {
1543        synchronized (mProcessStatsThread) {
1544            final long now = SystemClock.uptimeMillis();
1545            if (mLastCpuTime < (now-MONITOR_CPU_MIN_TIME)) {
1546                mProcessStatsThread.notify();
1547            }
1548        }
1549    }
1550
1551    void updateCpuStatsNow() {
1552        synchronized (mProcessStatsThread) {
1553            final long now = SystemClock.uptimeMillis();
1554            boolean haveNewCpuStats = false;
1555
1556            if (MONITOR_CPU_USAGE &&
1557                    mLastCpuTime < (now-MONITOR_CPU_MIN_TIME)) {
1558                mLastCpuTime = now;
1559                haveNewCpuStats = true;
1560                mProcessStats.update();
1561                //Log.i(TAG, mProcessStats.printCurrentState());
1562                //Log.i(TAG, "Total CPU usage: "
1563                //        + mProcessStats.getTotalCpuPercent() + "%");
1564
1565                // Log the cpu usage if the property is set.
1566                if ("true".equals(SystemProperties.get("events.cpu"))) {
1567                    int user = mProcessStats.getLastUserTime();
1568                    int system = mProcessStats.getLastSystemTime();
1569                    int iowait = mProcessStats.getLastIoWaitTime();
1570                    int irq = mProcessStats.getLastIrqTime();
1571                    int softIrq = mProcessStats.getLastSoftIrqTime();
1572                    int idle = mProcessStats.getLastIdleTime();
1573
1574                    int total = user + system + iowait + irq + softIrq + idle;
1575                    if (total == 0) total = 1;
1576
1577                    EventLog.writeEvent(LOG_CPU,
1578                            ((user+system+iowait+irq+softIrq) * 100) / total,
1579                            (user * 100) / total,
1580                            (system * 100) / total,
1581                            (iowait * 100) / total,
1582                            (irq * 100) / total,
1583                            (softIrq * 100) / total);
1584                }
1585            }
1586
1587            long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes();
1588            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
1589            synchronized(bstats) {
1590                synchronized(mPidsSelfLocked) {
1591                    if (haveNewCpuStats) {
1592                        if (mBatteryStatsService.isOnBattery()) {
1593                            final int N = mProcessStats.countWorkingStats();
1594                            for (int i=0; i<N; i++) {
1595                                ProcessStats.Stats st
1596                                        = mProcessStats.getWorkingStats(i);
1597                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
1598                                if (pr != null) {
1599                                    BatteryStatsImpl.Uid.Proc ps = pr.batteryStats;
1600                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
1601                                    ps.addSpeedStepTimes(cpuSpeedTimes);
1602                                } else {
1603                                    BatteryStatsImpl.Uid.Proc ps =
1604                                            bstats.getProcessStatsLocked(st.name, st.pid);
1605                                    if (ps != null) {
1606                                        ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
1607                                        ps.addSpeedStepTimes(cpuSpeedTimes);
1608                                    }
1609                                }
1610                            }
1611                        }
1612                    }
1613                }
1614
1615                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
1616                    mLastWriteTime = now;
1617                    mBatteryStatsService.getActiveStatistics().writeLocked();
1618                }
1619            }
1620        }
1621    }
1622
1623    /**
1624     * Initialize the application bind args. These are passed to each
1625     * process when the bindApplication() IPC is sent to the process. They're
1626     * lazily setup to make sure the services are running when they're asked for.
1627     */
1628    private HashMap<String, IBinder> getCommonServicesLocked() {
1629        if (mAppBindArgs == null) {
1630            mAppBindArgs = new HashMap<String, IBinder>();
1631
1632            // Setup the application init args
1633            mAppBindArgs.put("package", ServiceManager.getService("package"));
1634            mAppBindArgs.put("window", ServiceManager.getService("window"));
1635            mAppBindArgs.put(Context.ALARM_SERVICE,
1636                    ServiceManager.getService(Context.ALARM_SERVICE));
1637        }
1638        return mAppBindArgs;
1639    }
1640
1641    private final void setFocusedActivityLocked(HistoryRecord r) {
1642        if (mFocusedActivity != r) {
1643            mFocusedActivity = r;
1644            mWindowManager.setFocusedApp(r, true);
1645        }
1646    }
1647
1648    private final void updateLRUListLocked(ProcessRecord app,
1649            boolean oomAdj) {
1650        // put it on the LRU to keep track of when it should be exited.
1651        int lrui = mLRUProcesses.indexOf(app);
1652        if (lrui >= 0) mLRUProcesses.remove(lrui);
1653        mLRUProcesses.add(app);
1654        //Log.i(TAG, "Putting proc to front: " + app.processName);
1655        if (oomAdj) {
1656            updateOomAdjLocked();
1657        }
1658    }
1659
1660    private final boolean updateLRUListLocked(HistoryRecord r) {
1661        final boolean hadit = mLRUActivities.remove(r);
1662        mLRUActivities.add(r);
1663        return hadit;
1664    }
1665
1666    private final HistoryRecord topRunningActivityLocked(HistoryRecord notTop) {
1667        int i = mHistory.size()-1;
1668        while (i >= 0) {
1669            HistoryRecord r = (HistoryRecord)mHistory.get(i);
1670            if (!r.finishing && r != notTop) {
1671                return r;
1672            }
1673            i--;
1674        }
1675        return null;
1676    }
1677
1678    private final HistoryRecord topRunningNonDelayedActivityLocked(HistoryRecord notTop) {
1679        int i = mHistory.size()-1;
1680        while (i >= 0) {
1681            HistoryRecord r = (HistoryRecord)mHistory.get(i);
1682            if (!r.finishing && !r.delayedResume && r != notTop) {
1683                return r;
1684            }
1685            i--;
1686        }
1687        return null;
1688    }
1689
1690    /**
1691     * This is a simplified version of topRunningActivityLocked that provides a number of
1692     * optional skip-over modes.  It is intended for use with the ActivityController hook only.
1693     *
1694     * @param token If non-null, any history records matching this token will be skipped.
1695     * @param taskId If non-zero, we'll attempt to skip over records with the same task ID.
1696     *
1697     * @return Returns the HistoryRecord of the next activity on the stack.
1698     */
1699    private final HistoryRecord topRunningActivityLocked(IBinder token, int taskId) {
1700        int i = mHistory.size()-1;
1701        while (i >= 0) {
1702            HistoryRecord r = (HistoryRecord)mHistory.get(i);
1703            // Note: the taskId check depends on real taskId fields being non-zero
1704            if (!r.finishing && (token != r) && (taskId != r.task.taskId)) {
1705                return r;
1706            }
1707            i--;
1708        }
1709        return null;
1710    }
1711
1712    private final ProcessRecord getProcessRecordLocked(
1713            String processName, int uid) {
1714        if (uid == Process.SYSTEM_UID) {
1715            // The system gets to run in any process.  If there are multiple
1716            // processes with the same uid, just pick the first (this
1717            // should never happen).
1718            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(
1719                    processName);
1720            return procs != null ? procs.valueAt(0) : null;
1721        }
1722        ProcessRecord proc = mProcessNames.get(processName, uid);
1723        return proc;
1724    }
1725
1726    private void ensurePackageDexOpt(String packageName) {
1727        IPackageManager pm = ActivityThread.getPackageManager();
1728        try {
1729            if (pm.performDexOpt(packageName)) {
1730                mDidDexOpt = true;
1731            }
1732        } catch (RemoteException e) {
1733        }
1734    }
1735
1736    private boolean isNextTransitionForward() {
1737        int transit = mWindowManager.getPendingAppTransition();
1738        return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
1739                || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
1740                || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT;
1741    }
1742
1743    private final boolean realStartActivityLocked(HistoryRecord r,
1744            ProcessRecord app, boolean andResume, boolean checkConfig)
1745            throws RemoteException {
1746
1747        r.startFreezingScreenLocked(app, 0);
1748        mWindowManager.setAppVisibility(r, true);
1749
1750        // Have the window manager re-evaluate the orientation of
1751        // the screen based on the new activity order.  Note that
1752        // as a result of this, it can call back into the activity
1753        // manager with a new orientation.  We don't care about that,
1754        // because the activity is not currently running so we are
1755        // just restarting it anyway.
1756        if (checkConfig) {
1757            Configuration config = mWindowManager.updateOrientationFromAppTokens(
1758                    mConfiguration,
1759                    r.mayFreezeScreenLocked(app) ? r : null);
1760            updateConfigurationLocked(config, r);
1761        }
1762
1763        r.app = app;
1764
1765        if (localLOGV) Log.v(TAG, "Launching: " + r);
1766
1767        int idx = app.activities.indexOf(r);
1768        if (idx < 0) {
1769            app.activities.add(r);
1770        }
1771        updateLRUListLocked(app, true);
1772
1773        try {
1774            if (app.thread == null) {
1775                throw new RemoteException();
1776            }
1777            List<ResultInfo> results = null;
1778            List<Intent> newIntents = null;
1779            if (andResume) {
1780                results = r.results;
1781                newIntents = r.newIntents;
1782            }
1783            if (DEBUG_SWITCH) Log.v(TAG, "Launching: " + r
1784                    + " icicle=" + r.icicle
1785                    + " with results=" + results + " newIntents=" + newIntents
1786                    + " andResume=" + andResume);
1787            if (andResume) {
1788                EventLog.writeEvent(LOG_AM_RESTART_ACTIVITY,
1789                        System.identityHashCode(r),
1790                        r.task.taskId, r.shortComponentName);
1791            }
1792            if (r.isHomeActivity) {
1793                mHomeProcess = app;
1794            }
1795            ensurePackageDexOpt(r.intent.getComponent().getPackageName());
1796            app.thread.scheduleLaunchActivity(new Intent(r.intent), r,
1797                    System.identityHashCode(r),
1798                    r.info, r.icicle, results, newIntents, !andResume,
1799                    isNextTransitionForward());
1800        } catch (RemoteException e) {
1801            if (r.launchFailed) {
1802                // This is the second time we failed -- finish activity
1803                // and give up.
1804                Log.e(TAG, "Second failure launching "
1805                      + r.intent.getComponent().flattenToShortString()
1806                      + ", giving up", e);
1807                appDiedLocked(app, app.pid, app.thread);
1808                requestFinishActivityLocked(r, Activity.RESULT_CANCELED, null,
1809                        "2nd-crash");
1810                return false;
1811            }
1812
1813            // This is the first time we failed -- restart process and
1814            // retry.
1815            app.activities.remove(r);
1816            throw e;
1817        }
1818
1819        r.launchFailed = false;
1820        if (updateLRUListLocked(r)) {
1821            Log.w(TAG, "Activity " + r
1822                  + " being launched, but already in LRU list");
1823        }
1824
1825        if (andResume) {
1826            // As part of the process of launching, ActivityThread also performs
1827            // a resume.
1828            r.state = ActivityState.RESUMED;
1829            r.icicle = null;
1830            r.haveState = false;
1831            r.stopped = false;
1832            mResumedActivity = r;
1833            r.task.touchActiveTime();
1834            completeResumeLocked(r);
1835            pauseIfSleepingLocked();
1836        } else {
1837            // This activity is not starting in the resumed state... which
1838            // should look like we asked it to pause+stop (but remain visible),
1839            // and it has done so and reported back the current icicle and
1840            // other state.
1841            r.state = ActivityState.STOPPED;
1842            r.stopped = true;
1843        }
1844
1845        // Launch the new version setup screen if needed.  We do this -after-
1846        // launching the initial activity (that is, home), so that it can have
1847        // a chance to initialize itself while in the background, making the
1848        // switch back to it faster and look better.
1849        startSetupActivityLocked();
1850
1851        return true;
1852    }
1853
1854    private final void startSpecificActivityLocked(HistoryRecord r,
1855            boolean andResume, boolean checkConfig) {
1856        // Is this activity's application already running?
1857        ProcessRecord app = getProcessRecordLocked(r.processName,
1858                r.info.applicationInfo.uid);
1859
1860        if (r.startTime == 0) {
1861            r.startTime = SystemClock.uptimeMillis();
1862            if (mInitialStartTime == 0) {
1863                mInitialStartTime = r.startTime;
1864            }
1865        } else if (mInitialStartTime == 0) {
1866            mInitialStartTime = SystemClock.uptimeMillis();
1867        }
1868
1869        if (app != null && app.thread != null) {
1870            try {
1871                realStartActivityLocked(r, app, andResume, checkConfig);
1872                return;
1873            } catch (RemoteException e) {
1874                Log.w(TAG, "Exception when starting activity "
1875                        + r.intent.getComponent().flattenToShortString(), e);
1876            }
1877
1878            // If a dead object exception was thrown -- fall through to
1879            // restart the application.
1880        }
1881
1882        startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
1883                "activity", r.intent.getComponent(), false);
1884    }
1885
1886    private final ProcessRecord startProcessLocked(String processName,
1887            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
1888            String hostingType, ComponentName hostingName, boolean allowWhileBooting) {
1889        ProcessRecord app = getProcessRecordLocked(processName, info.uid);
1890        // We don't have to do anything more if:
1891        // (1) There is an existing application record; and
1892        // (2) The caller doesn't think it is dead, OR there is no thread
1893        //     object attached to it so we know it couldn't have crashed; and
1894        // (3) There is a pid assigned to it, so it is either starting or
1895        //     already running.
1896        if (DEBUG_PROCESSES) Log.v(TAG, "startProcess: name=" + processName
1897                + " app=" + app + " knownToBeDead=" + knownToBeDead
1898                + " thread=" + (app != null ? app.thread : null)
1899                + " pid=" + (app != null ? app.pid : -1));
1900        if (app != null &&
1901                (!knownToBeDead || app.thread == null) && app.pid > 0) {
1902            return app;
1903        }
1904
1905        String hostingNameStr = hostingName != null
1906                ? hostingName.flattenToShortString() : null;
1907
1908        if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
1909            // If we are in the background, then check to see if this process
1910            // is bad.  If so, we will just silently fail.
1911            if (mBadProcesses.get(info.processName, info.uid) != null) {
1912                return null;
1913            }
1914        } else {
1915            // When the user is explicitly starting a process, then clear its
1916            // crash count so that we won't make it bad until they see at
1917            // least one crash dialog again, and make the process good again
1918            // if it had been bad.
1919            mProcessCrashTimes.remove(info.processName, info.uid);
1920            if (mBadProcesses.get(info.processName, info.uid) != null) {
1921                EventLog.writeEvent(LOG_AM_PROCESS_GOOD, info.uid,
1922                        info.processName);
1923                mBadProcesses.remove(info.processName, info.uid);
1924                if (app != null) {
1925                    app.bad = false;
1926                }
1927            }
1928        }
1929
1930        if (app == null) {
1931            app = newProcessRecordLocked(null, info, processName);
1932            mProcessNames.put(processName, info.uid, app);
1933        } else {
1934            // If this is a new package in the process, add the package to the list
1935            app.addPackage(info.packageName);
1936        }
1937
1938        // If the system is not ready yet, then hold off on starting this
1939        // process until it is.
1940        if (!mSystemReady
1941                && !isAllowedWhileBooting(info)
1942                && !allowWhileBooting) {
1943            if (!mProcessesOnHold.contains(app)) {
1944                mProcessesOnHold.add(app);
1945            }
1946            return app;
1947        }
1948
1949        startProcessLocked(app, hostingType, hostingNameStr);
1950        return (app.pid != 0) ? app : null;
1951    }
1952
1953    boolean isAllowedWhileBooting(ApplicationInfo ai) {
1954        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
1955    }
1956
1957    private final void startProcessLocked(ProcessRecord app,
1958            String hostingType, String hostingNameStr) {
1959        if (app.pid > 0 && app.pid != MY_PID) {
1960            synchronized (mPidsSelfLocked) {
1961                mPidsSelfLocked.remove(app.pid);
1962                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
1963            }
1964            app.pid = 0;
1965        }
1966
1967        mProcessesOnHold.remove(app);
1968
1969        updateCpuStats();
1970
1971        System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1);
1972        mProcDeaths[0] = 0;
1973
1974        try {
1975            int uid = app.info.uid;
1976            int[] gids = null;
1977            try {
1978                gids = mContext.getPackageManager().getPackageGids(
1979                        app.info.packageName);
1980            } catch (PackageManager.NameNotFoundException e) {
1981                Log.w(TAG, "Unable to retrieve gids", e);
1982            }
1983            if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
1984                if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
1985                        && mTopComponent != null
1986                        && app.processName.equals(mTopComponent.getPackageName())) {
1987                    uid = 0;
1988                }
1989                if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
1990                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
1991                    uid = 0;
1992                }
1993            }
1994            int debugFlags = 0;
1995            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
1996                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
1997            }
1998            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
1999                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2000            }
2001            if ("1".equals(SystemProperties.get("debug.assert"))) {
2002                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2003            }
2004            int pid = Process.start("android.app.ActivityThread",
2005                    mSimpleProcessManagement ? app.processName : null, uid, uid,
2006                    gids, debugFlags, null);
2007            BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
2008            synchronized (bs) {
2009                if (bs.isOnBattery()) {
2010                    app.batteryStats.incStartsLocked();
2011                }
2012            }
2013
2014            EventLog.writeEvent(LOG_AM_PROCESS_START, pid, uid,
2015                    app.processName, hostingType,
2016                    hostingNameStr != null ? hostingNameStr : "");
2017
2018            if (app.persistent) {
2019                Watchdog.getInstance().processStarted(app, app.processName, pid);
2020            }
2021
2022            StringBuilder buf = mStringBuilder;
2023            buf.setLength(0);
2024            buf.append("Start proc ");
2025            buf.append(app.processName);
2026            buf.append(" for ");
2027            buf.append(hostingType);
2028            if (hostingNameStr != null) {
2029                buf.append(" ");
2030                buf.append(hostingNameStr);
2031            }
2032            buf.append(": pid=");
2033            buf.append(pid);
2034            buf.append(" uid=");
2035            buf.append(uid);
2036            buf.append(" gids={");
2037            if (gids != null) {
2038                for (int gi=0; gi<gids.length; gi++) {
2039                    if (gi != 0) buf.append(", ");
2040                    buf.append(gids[gi]);
2041
2042                }
2043            }
2044            buf.append("}");
2045            Log.i(TAG, buf.toString());
2046            if (pid == 0 || pid == MY_PID) {
2047                // Processes are being emulated with threads.
2048                app.pid = MY_PID;
2049                app.removed = false;
2050                mStartingProcesses.add(app);
2051            } else if (pid > 0) {
2052                app.pid = pid;
2053                app.removed = false;
2054                synchronized (mPidsSelfLocked) {
2055                    this.mPidsSelfLocked.put(pid, app);
2056                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2057                    msg.obj = app;
2058                    mHandler.sendMessageDelayed(msg, PROC_START_TIMEOUT);
2059                }
2060            } else {
2061                app.pid = 0;
2062                RuntimeException e = new RuntimeException(
2063                        "Failure starting process " + app.processName
2064                        + ": returned pid=" + pid);
2065                Log.e(TAG, e.getMessage(), e);
2066            }
2067        } catch (RuntimeException e) {
2068            // XXX do better error recovery.
2069            app.pid = 0;
2070            Log.e(TAG, "Failure starting process " + app.processName, e);
2071        }
2072    }
2073
2074    private final void startPausingLocked(boolean userLeaving, boolean uiSleeping) {
2075        if (mPausingActivity != null) {
2076            RuntimeException e = new RuntimeException();
2077            Log.e(TAG, "Trying to pause when pause is already pending for "
2078                  + mPausingActivity, e);
2079        }
2080        HistoryRecord prev = mResumedActivity;
2081        if (prev == null) {
2082            RuntimeException e = new RuntimeException();
2083            Log.e(TAG, "Trying to pause when nothing is resumed", e);
2084            resumeTopActivityLocked(null);
2085            return;
2086        }
2087        if (DEBUG_PAUSE) Log.v(TAG, "Start pausing: " + prev);
2088        mResumedActivity = null;
2089        mPausingActivity = prev;
2090        mLastPausedActivity = prev;
2091        prev.state = ActivityState.PAUSING;
2092        prev.task.touchActiveTime();
2093
2094        updateCpuStats();
2095
2096        if (prev.app != null && prev.app.thread != null) {
2097            if (DEBUG_PAUSE) Log.v(TAG, "Enqueueing pending pause: " + prev);
2098            try {
2099                EventLog.writeEvent(LOG_AM_PAUSE_ACTIVITY,
2100                        System.identityHashCode(prev),
2101                        prev.shortComponentName);
2102                prev.app.thread.schedulePauseActivity(prev, prev.finishing, userLeaving,
2103                        prev.configChangeFlags);
2104                updateUsageStats(prev, false);
2105            } catch (Exception e) {
2106                // Ignore exception, if process died other code will cleanup.
2107                Log.w(TAG, "Exception thrown during pause", e);
2108                mPausingActivity = null;
2109                mLastPausedActivity = null;
2110            }
2111        } else {
2112            mPausingActivity = null;
2113            mLastPausedActivity = null;
2114        }
2115
2116        // If we are not going to sleep, we want to ensure the device is
2117        // awake until the next activity is started.
2118        if (!mSleeping && !mShuttingDown) {
2119            mLaunchingActivity.acquire();
2120            if (!mHandler.hasMessages(LAUNCH_TIMEOUT_MSG)) {
2121                // To be safe, don't allow the wake lock to be held for too long.
2122                Message msg = mHandler.obtainMessage(LAUNCH_TIMEOUT_MSG);
2123                mHandler.sendMessageDelayed(msg, LAUNCH_TIMEOUT);
2124            }
2125        }
2126
2127
2128        if (mPausingActivity != null) {
2129            // Have the window manager pause its key dispatching until the new
2130            // activity has started.  If we're pausing the activity just because
2131            // the screen is being turned off and the UI is sleeping, don't interrupt
2132            // key dispatch; the same activity will pick it up again on wakeup.
2133            if (!uiSleeping) {
2134                prev.pauseKeyDispatchingLocked();
2135            } else {
2136                if (DEBUG_PAUSE) Log.v(TAG, "Key dispatch not paused for screen off");
2137            }
2138
2139            // Schedule a pause timeout in case the app doesn't respond.
2140            // We don't give it much time because this directly impacts the
2141            // responsiveness seen by the user.
2142            Message msg = mHandler.obtainMessage(PAUSE_TIMEOUT_MSG);
2143            msg.obj = prev;
2144            mHandler.sendMessageDelayed(msg, PAUSE_TIMEOUT);
2145            if (DEBUG_PAUSE) Log.v(TAG, "Waiting for pause to complete...");
2146        } else {
2147            // This activity failed to schedule the
2148            // pause, so just treat it as being paused now.
2149            if (DEBUG_PAUSE) Log.v(TAG, "Activity not running, resuming next.");
2150            resumeTopActivityLocked(null);
2151        }
2152    }
2153
2154    private final void completePauseLocked() {
2155        HistoryRecord prev = mPausingActivity;
2156        if (DEBUG_PAUSE) Log.v(TAG, "Complete pause: " + prev);
2157
2158        if (prev != null) {
2159            if (prev.finishing) {
2160                if (DEBUG_PAUSE) Log.v(TAG, "Executing finish of activity: " + prev);
2161                prev = finishCurrentActivityLocked(prev, FINISH_AFTER_VISIBLE);
2162            } else if (prev.app != null) {
2163                if (DEBUG_PAUSE) Log.v(TAG, "Enqueueing pending stop: " + prev);
2164                if (prev.waitingVisible) {
2165                    prev.waitingVisible = false;
2166                    mWaitingVisibleActivities.remove(prev);
2167                    if (DEBUG_SWITCH || DEBUG_PAUSE) Log.v(
2168                            TAG, "Complete pause, no longer waiting: " + prev);
2169                }
2170                if (prev.configDestroy) {
2171                    // The previous is being paused because the configuration
2172                    // is changing, which means it is actually stopping...
2173                    // To juggle the fact that we are also starting a new
2174                    // instance right now, we need to first completely stop
2175                    // the current instance before starting the new one.
2176                    if (DEBUG_PAUSE) Log.v(TAG, "Destroying after pause: " + prev);
2177                    destroyActivityLocked(prev, true);
2178                } else {
2179                    mStoppingActivities.add(prev);
2180                    if (mStoppingActivities.size() > 3) {
2181                        // If we already have a few activities waiting to stop,
2182                        // then give up on things going idle and start clearing
2183                        // them out.
2184                        if (DEBUG_PAUSE) Log.v(TAG, "To many pending stops, forcing idle");
2185                        Message msg = Message.obtain();
2186                        msg.what = ActivityManagerService.IDLE_NOW_MSG;
2187                        mHandler.sendMessage(msg);
2188                    }
2189                }
2190            } else {
2191                if (DEBUG_PAUSE) Log.v(TAG, "App died during pause, not stopping: " + prev);
2192                prev = null;
2193            }
2194            mPausingActivity = null;
2195        }
2196
2197        if (!mSleeping && !mShuttingDown) {
2198            resumeTopActivityLocked(prev);
2199        } else {
2200            if (mGoingToSleep.isHeld()) {
2201                mGoingToSleep.release();
2202            }
2203            if (mShuttingDown) {
2204                notifyAll();
2205            }
2206        }
2207
2208        if (prev != null) {
2209            prev.resumeKeyDispatchingLocked();
2210        }
2211
2212        if (prev.app != null && prev.cpuTimeAtResume > 0 && mBatteryStatsService.isOnBattery()) {
2213            long diff = 0;
2214            synchronized (mProcessStatsThread) {
2215                diff = mProcessStats.getCpuTimeForPid(prev.app.pid) - prev.cpuTimeAtResume;
2216            }
2217            if (diff > 0) {
2218                BatteryStatsImpl bsi = mBatteryStatsService.getActiveStatistics();
2219                synchronized (bsi) {
2220                    BatteryStatsImpl.Uid.Proc ps =
2221                            bsi.getProcessStatsLocked(prev.info.applicationInfo.uid,
2222                            prev.info.packageName);
2223                    if (ps != null) {
2224                        ps.addForegroundTimeLocked(diff);
2225                    }
2226                }
2227            }
2228        }
2229        prev.cpuTimeAtResume = 0; // reset it
2230    }
2231
2232    /**
2233     * Once we know that we have asked an application to put an activity in
2234     * the resumed state (either by launching it or explicitly telling it),
2235     * this function updates the rest of our state to match that fact.
2236     */
2237    private final void completeResumeLocked(HistoryRecord next) {
2238        next.idle = false;
2239        next.results = null;
2240        next.newIntents = null;
2241
2242        // schedule an idle timeout in case the app doesn't do it for us.
2243        Message msg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG);
2244        msg.obj = next;
2245        mHandler.sendMessageDelayed(msg, IDLE_TIMEOUT);
2246
2247        if (false) {
2248            // The activity was never told to pause, so just keep
2249            // things going as-is.  To maintain our own state,
2250            // we need to emulate it coming back and saying it is
2251            // idle.
2252            msg = mHandler.obtainMessage(IDLE_NOW_MSG);
2253            msg.obj = next;
2254            mHandler.sendMessage(msg);
2255        }
2256
2257        reportResumedActivityLocked(next);
2258
2259        next.thumbnail = null;
2260        setFocusedActivityLocked(next);
2261        next.resumeKeyDispatchingLocked();
2262        ensureActivitiesVisibleLocked(null, 0);
2263        mWindowManager.executeAppTransition();
2264        mNoAnimActivities.clear();
2265
2266        // Mark the point when the activity is resuming
2267        // TODO: To be more accurate, the mark should be before the onCreate,
2268        //       not after the onResume. But for subsequent starts, onResume is fine.
2269        if (next.app != null) {
2270            synchronized (mProcessStatsThread) {
2271                next.cpuTimeAtResume = mProcessStats.getCpuTimeForPid(next.app.pid);
2272            }
2273        } else {
2274            next.cpuTimeAtResume = 0; // Couldn't get the cpu time of process
2275        }
2276    }
2277
2278    /**
2279     * Make sure that all activities that need to be visible (that is, they
2280     * currently can be seen by the user) actually are.
2281     */
2282    private final void ensureActivitiesVisibleLocked(HistoryRecord top,
2283            HistoryRecord starting, String onlyThisProcess, int configChanges) {
2284        if (DEBUG_VISBILITY) Log.v(
2285                TAG, "ensureActivitiesVisible behind " + top
2286                + " configChanges=0x" + Integer.toHexString(configChanges));
2287
2288        // If the top activity is not fullscreen, then we need to
2289        // make sure any activities under it are now visible.
2290        final int count = mHistory.size();
2291        int i = count-1;
2292        while (mHistory.get(i) != top) {
2293            i--;
2294        }
2295        HistoryRecord r;
2296        boolean behindFullscreen = false;
2297        for (; i>=0; i--) {
2298            r = (HistoryRecord)mHistory.get(i);
2299            if (DEBUG_VISBILITY) Log.v(
2300                    TAG, "Make visible? " + r + " finishing=" + r.finishing
2301                    + " state=" + r.state);
2302            if (r.finishing) {
2303                continue;
2304            }
2305
2306            final boolean doThisProcess = onlyThisProcess == null
2307                    || onlyThisProcess.equals(r.processName);
2308
2309            // First: if this is not the current activity being started, make
2310            // sure it matches the current configuration.
2311            if (r != starting && doThisProcess) {
2312                ensureActivityConfigurationLocked(r, 0);
2313            }
2314
2315            if (r.app == null || r.app.thread == null) {
2316                if (onlyThisProcess == null
2317                        || onlyThisProcess.equals(r.processName)) {
2318                    // This activity needs to be visible, but isn't even
2319                    // running...  get it started, but don't resume it
2320                    // at this point.
2321                    if (DEBUG_VISBILITY) Log.v(
2322                            TAG, "Start and freeze screen for " + r);
2323                    if (r != starting) {
2324                        r.startFreezingScreenLocked(r.app, configChanges);
2325                    }
2326                    if (!r.visible) {
2327                        if (DEBUG_VISBILITY) Log.v(
2328                                TAG, "Starting and making visible: " + r);
2329                        mWindowManager.setAppVisibility(r, true);
2330                    }
2331                    if (r != starting) {
2332                        startSpecificActivityLocked(r, false, false);
2333                    }
2334                }
2335
2336            } else if (r.visible) {
2337                // If this activity is already visible, then there is nothing
2338                // else to do here.
2339                if (DEBUG_VISBILITY) Log.v(
2340                        TAG, "Skipping: already visible at " + r);
2341                r.stopFreezingScreenLocked(false);
2342
2343            } else if (onlyThisProcess == null) {
2344                // This activity is not currently visible, but is running.
2345                // Tell it to become visible.
2346                r.visible = true;
2347                if (r.state != ActivityState.RESUMED && r != starting) {
2348                    // If this activity is paused, tell it
2349                    // to now show its window.
2350                    if (DEBUG_VISBILITY) Log.v(
2351                            TAG, "Making visible and scheduling visibility: " + r);
2352                    try {
2353                        mWindowManager.setAppVisibility(r, true);
2354                        r.app.thread.scheduleWindowVisibility(r, true);
2355                        r.stopFreezingScreenLocked(false);
2356                    } catch (Exception e) {
2357                        // Just skip on any failure; we'll make it
2358                        // visible when it next restarts.
2359                        Log.w(TAG, "Exception thrown making visibile: "
2360                                + r.intent.getComponent(), e);
2361                    }
2362                }
2363            }
2364
2365            // Aggregate current change flags.
2366            configChanges |= r.configChangeFlags;
2367
2368            if (r.fullscreen) {
2369                // At this point, nothing else needs to be shown
2370                if (DEBUG_VISBILITY) Log.v(
2371                        TAG, "Stopping: fullscreen at " + r);
2372                behindFullscreen = true;
2373                i--;
2374                break;
2375            }
2376        }
2377
2378        // Now for any activities that aren't visible to the user, make
2379        // sure they no longer are keeping the screen frozen.
2380        while (i >= 0) {
2381            r = (HistoryRecord)mHistory.get(i);
2382            if (DEBUG_VISBILITY) Log.v(
2383                    TAG, "Make invisible? " + r + " finishing=" + r.finishing
2384                    + " state=" + r.state
2385                    + " behindFullscreen=" + behindFullscreen);
2386            if (!r.finishing) {
2387                if (behindFullscreen) {
2388                    if (r.visible) {
2389                        if (DEBUG_VISBILITY) Log.v(
2390                                TAG, "Making invisible: " + r);
2391                        r.visible = false;
2392                        try {
2393                            mWindowManager.setAppVisibility(r, false);
2394                            if ((r.state == ActivityState.STOPPING
2395                                    || r.state == ActivityState.STOPPED)
2396                                    && r.app != null && r.app.thread != null) {
2397                                if (DEBUG_VISBILITY) Log.v(
2398                                        TAG, "Scheduling invisibility: " + r);
2399                                r.app.thread.scheduleWindowVisibility(r, false);
2400                            }
2401                        } catch (Exception e) {
2402                            // Just skip on any failure; we'll make it
2403                            // visible when it next restarts.
2404                            Log.w(TAG, "Exception thrown making hidden: "
2405                                    + r.intent.getComponent(), e);
2406                        }
2407                    } else {
2408                        if (DEBUG_VISBILITY) Log.v(
2409                                TAG, "Already invisible: " + r);
2410                    }
2411                } else if (r.fullscreen) {
2412                    if (DEBUG_VISBILITY) Log.v(
2413                            TAG, "Now behindFullscreen: " + r);
2414                    behindFullscreen = true;
2415                }
2416            }
2417            i--;
2418        }
2419    }
2420
2421    /**
2422     * Version of ensureActivitiesVisible that can easily be called anywhere.
2423     */
2424    private final void ensureActivitiesVisibleLocked(HistoryRecord starting,
2425            int configChanges) {
2426        HistoryRecord r = topRunningActivityLocked(null);
2427        if (r != null) {
2428            ensureActivitiesVisibleLocked(r, starting, null, configChanges);
2429        }
2430    }
2431
2432    private void updateUsageStats(HistoryRecord resumedComponent, boolean resumed) {
2433        if (resumed) {
2434            mUsageStatsService.noteResumeComponent(resumedComponent.realActivity);
2435        } else {
2436            mUsageStatsService.notePauseComponent(resumedComponent.realActivity);
2437        }
2438    }
2439
2440    private boolean startHomeActivityLocked() {
2441        if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2442                && mTopAction == null) {
2443            // We are running in factory test mode, but unable to find
2444            // the factory test app, so just sit around displaying the
2445            // error message and don't try to start anything.
2446            return false;
2447        }
2448        Intent intent = new Intent(
2449            mTopAction,
2450            mTopData != null ? Uri.parse(mTopData) : null);
2451        intent.setComponent(mTopComponent);
2452        if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
2453            intent.addCategory(Intent.CATEGORY_HOME);
2454        }
2455        ActivityInfo aInfo =
2456            intent.resolveActivityInfo(mContext.getPackageManager(),
2457                    STOCK_PM_FLAGS);
2458        if (aInfo != null) {
2459            intent.setComponent(new ComponentName(
2460                    aInfo.applicationInfo.packageName, aInfo.name));
2461            // Don't do this if the home app is currently being
2462            // instrumented.
2463            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2464                    aInfo.applicationInfo.uid);
2465            if (app == null || app.instrumentationClass == null) {
2466                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
2467                startActivityLocked(null, intent, null, null, 0, aInfo,
2468                        null, null, 0, 0, 0, false, false);
2469            }
2470        }
2471
2472
2473        return true;
2474    }
2475
2476    /**
2477     * Starts the "new version setup screen" if appropriate.
2478     */
2479    private void startSetupActivityLocked() {
2480        // Only do this once per boot.
2481        if (mCheckedForSetup) {
2482            return;
2483        }
2484
2485        // We will show this screen if the current one is a different
2486        // version than the last one shown, and we are not running in
2487        // low-level factory test mode.
2488        final ContentResolver resolver = mContext.getContentResolver();
2489        if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL &&
2490                Settings.Secure.getInt(resolver,
2491                        Settings.Secure.DEVICE_PROVISIONED, 0) != 0) {
2492            mCheckedForSetup = true;
2493
2494            // See if we should be showing the platform update setup UI.
2495            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
2496            List<ResolveInfo> ris = mSelf.mContext.getPackageManager()
2497                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
2498
2499            // We don't allow third party apps to replace this.
2500            ResolveInfo ri = null;
2501            for (int i=0; ris != null && i<ris.size(); i++) {
2502                if ((ris.get(i).activityInfo.applicationInfo.flags
2503                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
2504                    ri = ris.get(i);
2505                    break;
2506                }
2507            }
2508
2509            if (ri != null) {
2510                String vers = ri.activityInfo.metaData != null
2511                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2512                        : null;
2513                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2514                    vers = ri.activityInfo.applicationInfo.metaData.getString(
2515                            Intent.METADATA_SETUP_VERSION);
2516                }
2517                String lastVers = Settings.Secure.getString(
2518                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
2519                if (vers != null && !vers.equals(lastVers)) {
2520                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2521                    intent.setComponent(new ComponentName(
2522                            ri.activityInfo.packageName, ri.activityInfo.name));
2523                    startActivityLocked(null, intent, null, null, 0, ri.activityInfo,
2524                            null, null, 0, 0, 0, false, false);
2525                }
2526            }
2527        }
2528    }
2529
2530    private void reportResumedActivityLocked(HistoryRecord r) {
2531        //Log.i(TAG, "**** REPORT RESUME: " + r);
2532
2533        final int identHash = System.identityHashCode(r);
2534        updateUsageStats(r, true);
2535
2536        int i = mWatchers.beginBroadcast();
2537        while (i > 0) {
2538            i--;
2539            IActivityWatcher w = mWatchers.getBroadcastItem(i);
2540            if (w != null) {
2541                try {
2542                    w.activityResuming(identHash);
2543                } catch (RemoteException e) {
2544                }
2545            }
2546        }
2547        mWatchers.finishBroadcast();
2548    }
2549
2550    /**
2551     * Ensure that the top activity in the stack is resumed.
2552     *
2553     * @param prev The previously resumed activity, for when in the process
2554     * of pausing; can be null to call from elsewhere.
2555     *
2556     * @return Returns true if something is being resumed, or false if
2557     * nothing happened.
2558     */
2559    private final boolean resumeTopActivityLocked(HistoryRecord prev) {
2560        // Find the first activity that is not finishing.
2561        HistoryRecord next = topRunningActivityLocked(null);
2562
2563        // Remember how we'll process this pause/resume situation, and ensure
2564        // that the state is reset however we wind up proceeding.
2565        final boolean userLeaving = mUserLeaving;
2566        mUserLeaving = false;
2567
2568        if (next == null) {
2569            // There are no more activities!  Let's just start up the
2570            // Launcher...
2571            return startHomeActivityLocked();
2572        }
2573
2574        next.delayedResume = false;
2575
2576        // If the top activity is the resumed one, nothing to do.
2577        if (mResumedActivity == next && next.state == ActivityState.RESUMED) {
2578            // Make sure we have executed any pending transitions, since there
2579            // should be nothing left to do at this point.
2580            mWindowManager.executeAppTransition();
2581            mNoAnimActivities.clear();
2582            return false;
2583        }
2584
2585        // If we are sleeping, and there is no resumed activity, and the top
2586        // activity is paused, well that is the state we want.
2587        if ((mSleeping || mShuttingDown)
2588                && mLastPausedActivity == next && next.state == ActivityState.PAUSED) {
2589            // Make sure we have executed any pending transitions, since there
2590            // should be nothing left to do at this point.
2591            mWindowManager.executeAppTransition();
2592            mNoAnimActivities.clear();
2593            return false;
2594        }
2595
2596        // The activity may be waiting for stop, but that is no longer
2597        // appropriate for it.
2598        mStoppingActivities.remove(next);
2599        mWaitingVisibleActivities.remove(next);
2600
2601        if (DEBUG_SWITCH) Log.v(TAG, "Resuming " + next);
2602
2603        // If we are currently pausing an activity, then don't do anything
2604        // until that is done.
2605        if (mPausingActivity != null) {
2606            if (DEBUG_SWITCH) Log.v(TAG, "Skip resume: pausing=" + mPausingActivity);
2607            return false;
2608        }
2609
2610        // We need to start pausing the current activity so the top one
2611        // can be resumed...
2612        if (mResumedActivity != null) {
2613            if (DEBUG_SWITCH) Log.v(TAG, "Skip resume: need to start pausing");
2614            startPausingLocked(userLeaving, false);
2615            return true;
2616        }
2617
2618        if (prev != null && prev != next) {
2619            if (!prev.waitingVisible && next != null && !next.nowVisible) {
2620                prev.waitingVisible = true;
2621                mWaitingVisibleActivities.add(prev);
2622                if (DEBUG_SWITCH) Log.v(
2623                        TAG, "Resuming top, waiting visible to hide: " + prev);
2624            } else {
2625                // The next activity is already visible, so hide the previous
2626                // activity's windows right now so we can show the new one ASAP.
2627                // We only do this if the previous is finishing, which should mean
2628                // it is on top of the one being resumed so hiding it quickly
2629                // is good.  Otherwise, we want to do the normal route of allowing
2630                // the resumed activity to be shown so we can decide if the
2631                // previous should actually be hidden depending on whether the
2632                // new one is found to be full-screen or not.
2633                if (prev.finishing) {
2634                    mWindowManager.setAppVisibility(prev, false);
2635                    if (DEBUG_SWITCH) Log.v(TAG, "Not waiting for visible to hide: "
2636                            + prev + ", waitingVisible="
2637                            + (prev != null ? prev.waitingVisible : null)
2638                            + ", nowVisible=" + next.nowVisible);
2639                } else {
2640                    if (DEBUG_SWITCH) Log.v(TAG, "Previous already visible but still waiting to hide: "
2641                        + prev + ", waitingVisible="
2642                        + (prev != null ? prev.waitingVisible : null)
2643                        + ", nowVisible=" + next.nowVisible);
2644                }
2645            }
2646        }
2647
2648        // We are starting up the next activity, so tell the window manager
2649        // that the previous one will be hidden soon.  This way it can know
2650        // to ignore it when computing the desired screen orientation.
2651        if (prev != null) {
2652            if (prev.finishing) {
2653                if (DEBUG_TRANSITION) Log.v(TAG,
2654                        "Prepare close transition: prev=" + prev);
2655                if (mNoAnimActivities.contains(prev)) {
2656                    mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_NONE);
2657                } else {
2658                    mWindowManager.prepareAppTransition(prev.task == next.task
2659                            ? WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE
2660                            : WindowManagerPolicy.TRANSIT_TASK_CLOSE);
2661                }
2662                mWindowManager.setAppWillBeHidden(prev);
2663                mWindowManager.setAppVisibility(prev, false);
2664            } else {
2665                if (DEBUG_TRANSITION) Log.v(TAG,
2666                        "Prepare open transition: prev=" + prev);
2667                if (mNoAnimActivities.contains(next)) {
2668                    mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_NONE);
2669                } else {
2670                    mWindowManager.prepareAppTransition(prev.task == next.task
2671                            ? WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
2672                            : WindowManagerPolicy.TRANSIT_TASK_OPEN);
2673                }
2674            }
2675            if (false) {
2676                mWindowManager.setAppWillBeHidden(prev);
2677                mWindowManager.setAppVisibility(prev, false);
2678            }
2679        } else if (mHistory.size() > 1) {
2680            if (DEBUG_TRANSITION) Log.v(TAG,
2681                    "Prepare open transition: no previous");
2682            if (mNoAnimActivities.contains(next)) {
2683                mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_NONE);
2684            } else {
2685                mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN);
2686            }
2687        }
2688
2689        if (next.app != null && next.app.thread != null) {
2690            if (DEBUG_SWITCH) Log.v(TAG, "Resume running: " + next);
2691
2692            // This activity is now becoming visible.
2693            mWindowManager.setAppVisibility(next, true);
2694
2695            HistoryRecord lastResumedActivity = mResumedActivity;
2696            ActivityState lastState = next.state;
2697
2698            updateCpuStats();
2699
2700            next.state = ActivityState.RESUMED;
2701            mResumedActivity = next;
2702            next.task.touchActiveTime();
2703            updateLRUListLocked(next.app, true);
2704            updateLRUListLocked(next);
2705
2706            // Have the window manager re-evaluate the orientation of
2707            // the screen based on the new activity order.
2708            boolean updated;
2709            synchronized (this) {
2710                Configuration config = mWindowManager.updateOrientationFromAppTokens(
2711                        mConfiguration,
2712                        next.mayFreezeScreenLocked(next.app) ? next : null);
2713                if (config != null) {
2714                    /*
2715                     * Explicitly restore the locale to the one from the
2716                     * old configuration, since the one that comes back from
2717                     * the window manager has the default (boot) locale.
2718                     *
2719                     * It looks like previously the locale picker only worked
2720                     * by coincidence: usually it would do its setting of
2721                     * the locale after the activity transition, so it didn't
2722                     * matter that this lost it.  With the synchronized
2723                     * block now keeping them from happening at the same time,
2724                     * this one always would happen second and undo what the
2725                     * locale picker had just done.
2726                     */
2727                    config.locale = mConfiguration.locale;
2728                    next.frozenBeforeDestroy = true;
2729                }
2730                updated = updateConfigurationLocked(config, next);
2731            }
2732            if (!updated) {
2733                // The configuration update wasn't able to keep the existing
2734                // instance of the activity, and instead started a new one.
2735                // We should be all done, but let's just make sure our activity
2736                // is still at the top and schedule another run if something
2737                // weird happened.
2738                HistoryRecord nextNext = topRunningActivityLocked(null);
2739                if (DEBUG_SWITCH) Log.i(TAG,
2740                        "Activity config changed during resume: " + next
2741                        + ", new next: " + nextNext);
2742                if (nextNext != next) {
2743                    // Do over!
2744                    mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG);
2745                }
2746                setFocusedActivityLocked(next);
2747                ensureActivitiesVisibleLocked(null, 0);
2748                mWindowManager.executeAppTransition();
2749                mNoAnimActivities.clear();
2750                return true;
2751            }
2752
2753            try {
2754                // Deliver all pending results.
2755                ArrayList a = next.results;
2756                if (a != null) {
2757                    final int N = a.size();
2758                    if (!next.finishing && N > 0) {
2759                        if (DEBUG_RESULTS) Log.v(
2760                                TAG, "Delivering results to " + next
2761                                + ": " + a);
2762                        next.app.thread.scheduleSendResult(next, a);
2763                    }
2764                }
2765
2766                if (next.newIntents != null) {
2767                    next.app.thread.scheduleNewIntent(next.newIntents, next);
2768                }
2769
2770                EventLog.writeEvent(LOG_AM_RESUME_ACTIVITY,
2771                        System.identityHashCode(next),
2772                        next.task.taskId, next.shortComponentName);
2773
2774                next.app.thread.scheduleResumeActivity(next,
2775                        isNextTransitionForward());
2776
2777                pauseIfSleepingLocked();
2778
2779            } catch (Exception e) {
2780                // Whoops, need to restart this activity!
2781                next.state = lastState;
2782                mResumedActivity = lastResumedActivity;
2783                if (Config.LOGD) Log.d(TAG,
2784                        "Restarting because process died: " + next);
2785                if (!next.hasBeenLaunched) {
2786                    next.hasBeenLaunched = true;
2787                } else {
2788                    if (SHOW_APP_STARTING_ICON) {
2789                        mWindowManager.setAppStartingWindow(
2790                                next, next.packageName, next.theme,
2791                                next.nonLocalizedLabel,
2792                                next.labelRes, next.icon, null, true);
2793                    }
2794                }
2795                startSpecificActivityLocked(next, true, false);
2796                return true;
2797            }
2798
2799            // From this point on, if something goes wrong there is no way
2800            // to recover the activity.
2801            try {
2802                next.visible = true;
2803                completeResumeLocked(next);
2804            } catch (Exception e) {
2805                // If any exception gets thrown, toss away this
2806                // activity and try the next one.
2807                Log.w(TAG, "Exception thrown during resume of " + next, e);
2808                requestFinishActivityLocked(next, Activity.RESULT_CANCELED, null,
2809                        "resume-exception");
2810                return true;
2811            }
2812
2813            // Didn't need to use the icicle, and it is now out of date.
2814            next.icicle = null;
2815            next.haveState = false;
2816            next.stopped = false;
2817
2818        } else {
2819            // Whoops, need to restart this activity!
2820            if (!next.hasBeenLaunched) {
2821                next.hasBeenLaunched = true;
2822            } else {
2823                if (SHOW_APP_STARTING_ICON) {
2824                    mWindowManager.setAppStartingWindow(
2825                            next, next.packageName, next.theme,
2826                            next.nonLocalizedLabel,
2827                            next.labelRes, next.icon, null, true);
2828                }
2829                if (DEBUG_SWITCH) Log.v(TAG, "Restarting: " + next);
2830            }
2831            startSpecificActivityLocked(next, true, true);
2832        }
2833
2834        return true;
2835    }
2836
2837    private final void startActivityLocked(HistoryRecord r, boolean newTask,
2838            boolean doResume) {
2839        final int NH = mHistory.size();
2840
2841        int addPos = -1;
2842
2843        if (!newTask) {
2844            // If starting in an existing task, find where that is...
2845            HistoryRecord next = null;
2846            boolean startIt = true;
2847            for (int i = NH-1; i >= 0; i--) {
2848                HistoryRecord p = (HistoryRecord)mHistory.get(i);
2849                if (p.finishing) {
2850                    continue;
2851                }
2852                if (p.task == r.task) {
2853                    // Here it is!  Now, if this is not yet visible to the
2854                    // user, then just add it without starting; it will
2855                    // get started when the user navigates back to it.
2856                    addPos = i+1;
2857                    if (!startIt) {
2858                        mHistory.add(addPos, r);
2859                        r.inHistory = true;
2860                        r.task.numActivities++;
2861                        mWindowManager.addAppToken(addPos, r, r.task.taskId,
2862                                r.info.screenOrientation, r.fullscreen);
2863                        if (VALIDATE_TOKENS) {
2864                            mWindowManager.validateAppTokens(mHistory);
2865                        }
2866                        return;
2867                    }
2868                    break;
2869                }
2870                if (p.fullscreen) {
2871                    startIt = false;
2872                }
2873                next = p;
2874            }
2875        }
2876
2877        // Place a new activity at top of stack, so it is next to interact
2878        // with the user.
2879        if (addPos < 0) {
2880            addPos = mHistory.size();
2881        }
2882
2883        // If we are not placing the new activity frontmost, we do not want
2884        // to deliver the onUserLeaving callback to the actual frontmost
2885        // activity
2886        if (addPos < NH) {
2887            mUserLeaving = false;
2888            if (DEBUG_USER_LEAVING) Log.v(TAG, "startActivity() behind front, mUserLeaving=false");
2889        }
2890
2891        // Slot the activity into the history stack and proceed
2892        mHistory.add(addPos, r);
2893        r.inHistory = true;
2894        r.frontOfTask = newTask;
2895        r.task.numActivities++;
2896        if (NH > 0) {
2897            // We want to show the starting preview window if we are
2898            // switching to a new task, or the next activity's process is
2899            // not currently running.
2900            boolean showStartingIcon = newTask;
2901            ProcessRecord proc = r.app;
2902            if (proc == null) {
2903                proc = mProcessNames.get(r.processName, r.info.applicationInfo.uid);
2904            }
2905            if (proc == null || proc.thread == null) {
2906                showStartingIcon = true;
2907            }
2908            if (DEBUG_TRANSITION) Log.v(TAG,
2909                    "Prepare open transition: starting " + r);
2910            if ((r.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) {
2911                mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_NONE);
2912                mNoAnimActivities.add(r);
2913            } else if ((r.intent.getFlags()&Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0) {
2914                mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_TASK_OPEN);
2915                mNoAnimActivities.remove(r);
2916            } else {
2917                mWindowManager.prepareAppTransition(newTask
2918                        ? WindowManagerPolicy.TRANSIT_TASK_OPEN
2919                        : WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN);
2920                mNoAnimActivities.remove(r);
2921            }
2922            mWindowManager.addAppToken(
2923                    addPos, r, r.task.taskId, r.info.screenOrientation, r.fullscreen);
2924            boolean doShow = true;
2925            if (newTask) {
2926                // Even though this activity is starting fresh, we still need
2927                // to reset it to make sure we apply affinities to move any
2928                // existing activities from other tasks in to it.
2929                // If the caller has requested that the target task be
2930                // reset, then do so.
2931                if ((r.intent.getFlags()
2932                        &Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
2933                    resetTaskIfNeededLocked(r, r);
2934                    doShow = topRunningNonDelayedActivityLocked(null) == r;
2935                }
2936            }
2937            if (SHOW_APP_STARTING_ICON && doShow) {
2938                // Figure out if we are transitioning from another activity that is
2939                // "has the same starting icon" as the next one.  This allows the
2940                // window manager to keep the previous window it had previously
2941                // created, if it still had one.
2942                HistoryRecord prev = mResumedActivity;
2943                if (prev != null) {
2944                    // We don't want to reuse the previous starting preview if:
2945                    // (1) The current activity is in a different task.
2946                    if (prev.task != r.task) prev = null;
2947                    // (2) The current activity is already displayed.
2948                    else if (prev.nowVisible) prev = null;
2949                }
2950                mWindowManager.setAppStartingWindow(
2951                        r, r.packageName, r.theme, r.nonLocalizedLabel,
2952                        r.labelRes, r.icon, prev, showStartingIcon);
2953            }
2954        } else {
2955            // If this is the first activity, don't do any fancy animations,
2956            // because there is nothing for it to animate on top of.
2957            mWindowManager.addAppToken(addPos, r, r.task.taskId,
2958                    r.info.screenOrientation, r.fullscreen);
2959        }
2960        if (VALIDATE_TOKENS) {
2961            mWindowManager.validateAppTokens(mHistory);
2962        }
2963
2964        if (doResume) {
2965            resumeTopActivityLocked(null);
2966        }
2967    }
2968
2969    /**
2970     * Perform clear operation as requested by
2971     * {@link Intent#FLAG_ACTIVITY_CLEAR_TOP}: search from the top of the
2972     * stack to the given task, then look for
2973     * an instance of that activity in the stack and, if found, finish all
2974     * activities on top of it and return the instance.
2975     *
2976     * @param newR Description of the new activity being started.
2977     * @return Returns the old activity that should be continue to be used,
2978     * or null if none was found.
2979     */
2980    private final HistoryRecord performClearTaskLocked(int taskId,
2981            HistoryRecord newR, int launchFlags, boolean doClear) {
2982        int i = mHistory.size();
2983
2984        // First find the requested task.
2985        while (i > 0) {
2986            i--;
2987            HistoryRecord r = (HistoryRecord)mHistory.get(i);
2988            if (r.task.taskId == taskId) {
2989                i++;
2990                break;
2991            }
2992        }
2993
2994        // Now clear it.
2995        while (i > 0) {
2996            i--;
2997            HistoryRecord r = (HistoryRecord)mHistory.get(i);
2998            if (r.finishing) {
2999                continue;
3000            }
3001            if (r.task.taskId != taskId) {
3002                return null;
3003            }
3004            if (r.realActivity.equals(newR.realActivity)) {
3005                // Here it is!  Now finish everything in front...
3006                HistoryRecord ret = r;
3007                if (doClear) {
3008                    while (i < (mHistory.size()-1)) {
3009                        i++;
3010                        r = (HistoryRecord)mHistory.get(i);
3011                        if (r.finishing) {
3012                            continue;
3013                        }
3014                        if (finishActivityLocked(r, i, Activity.RESULT_CANCELED,
3015                                null, "clear")) {
3016                            i--;
3017                        }
3018                    }
3019                }
3020
3021                // Finally, if this is a normal launch mode (that is, not
3022                // expecting onNewIntent()), then we will finish the current
3023                // instance of the activity so a new fresh one can be started.
3024                if (ret.launchMode == ActivityInfo.LAUNCH_MULTIPLE
3025                        && (launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) == 0) {
3026                    if (!ret.finishing) {
3027                        int index = indexOfTokenLocked(ret);
3028                        if (index >= 0) {
3029                            finishActivityLocked(ret, 0, Activity.RESULT_CANCELED,
3030                                    null, "clear");
3031                        }
3032                        return null;
3033                    }
3034                }
3035
3036                return ret;
3037            }
3038        }
3039
3040        return null;
3041    }
3042
3043    /**
3044     * Find the activity in the history stack within the given task.  Returns
3045     * the index within the history at which it's found, or < 0 if not found.
3046     */
3047    private final int findActivityInHistoryLocked(HistoryRecord r, int task) {
3048        int i = mHistory.size();
3049        while (i > 0) {
3050            i--;
3051            HistoryRecord candidate = (HistoryRecord)mHistory.get(i);
3052            if (candidate.task.taskId != task) {
3053                break;
3054            }
3055            if (candidate.realActivity.equals(r.realActivity)) {
3056                return i;
3057            }
3058        }
3059
3060        return -1;
3061    }
3062
3063    /**
3064     * Reorder the history stack so that the activity at the given index is
3065     * brought to the front.
3066     */
3067    private final HistoryRecord moveActivityToFrontLocked(int where) {
3068        HistoryRecord newTop = (HistoryRecord)mHistory.remove(where);
3069        int top = mHistory.size();
3070        HistoryRecord oldTop = (HistoryRecord)mHistory.get(top-1);
3071        mHistory.add(top, newTop);
3072        oldTop.frontOfTask = false;
3073        newTop.frontOfTask = true;
3074        return newTop;
3075    }
3076
3077    /**
3078     * Deliver a new Intent to an existing activity, so that its onNewIntent()
3079     * method will be called at the proper time.
3080     */
3081    private final void deliverNewIntentLocked(HistoryRecord r, Intent intent) {
3082        boolean sent = false;
3083        if (r.state == ActivityState.RESUMED
3084                && r.app != null && r.app.thread != null) {
3085            try {
3086                ArrayList<Intent> ar = new ArrayList<Intent>();
3087                ar.add(new Intent(intent));
3088                r.app.thread.scheduleNewIntent(ar, r);
3089                sent = true;
3090            } catch (Exception e) {
3091                Log.w(TAG, "Exception thrown sending new intent to " + r, e);
3092            }
3093        }
3094        if (!sent) {
3095            r.addNewIntentLocked(new Intent(intent));
3096        }
3097    }
3098
3099    private final void logStartActivity(int tag, HistoryRecord r,
3100            TaskRecord task) {
3101        EventLog.writeEvent(tag,
3102                System.identityHashCode(r), task.taskId,
3103                r.shortComponentName, r.intent.getAction(),
3104                r.intent.getType(), r.intent.getDataString(),
3105                r.intent.getFlags());
3106    }
3107
3108    private final int startActivityLocked(IApplicationThread caller,
3109            Intent intent, String resolvedType,
3110            Uri[] grantedUriPermissions,
3111            int grantedMode, ActivityInfo aInfo, IBinder resultTo,
3112            String resultWho, int requestCode,
3113            int callingPid, int callingUid, boolean onlyIfNeeded,
3114            boolean componentSpecified) {
3115        Log.i(TAG, "Starting activity: " + intent);
3116
3117        HistoryRecord sourceRecord = null;
3118        HistoryRecord resultRecord = null;
3119        if (resultTo != null) {
3120            int index = indexOfTokenLocked(resultTo);
3121            if (DEBUG_RESULTS) Log.v(
3122                TAG, "Sending result to " + resultTo + " (index " + index + ")");
3123            if (index >= 0) {
3124                sourceRecord = (HistoryRecord)mHistory.get(index);
3125                if (requestCode >= 0 && !sourceRecord.finishing) {
3126                    resultRecord = sourceRecord;
3127                }
3128            }
3129        }
3130
3131        int launchFlags = intent.getFlags();
3132
3133        if ((launchFlags&Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0
3134                && sourceRecord != null) {
3135            // Transfer the result target from the source activity to the new
3136            // one being started, including any failures.
3137            if (requestCode >= 0) {
3138                return START_FORWARD_AND_REQUEST_CONFLICT;
3139            }
3140            resultRecord = sourceRecord.resultTo;
3141            resultWho = sourceRecord.resultWho;
3142            requestCode = sourceRecord.requestCode;
3143            sourceRecord.resultTo = null;
3144            if (resultRecord != null) {
3145                resultRecord.removeResultsLocked(
3146                    sourceRecord, resultWho, requestCode);
3147            }
3148        }
3149
3150        int err = START_SUCCESS;
3151
3152        if (intent.getComponent() == null) {
3153            // We couldn't find a class that can handle the given Intent.
3154            // That's the end of that!
3155            err = START_INTENT_NOT_RESOLVED;
3156        }
3157
3158        if (err == START_SUCCESS && aInfo == null) {
3159            // We couldn't find the specific class specified in the Intent.
3160            // Also the end of the line.
3161            err = START_CLASS_NOT_FOUND;
3162        }
3163
3164        ProcessRecord callerApp = null;
3165        if (err == START_SUCCESS && caller != null) {
3166            callerApp = getRecordForAppLocked(caller);
3167            if (callerApp != null) {
3168                callingPid = callerApp.pid;
3169                callingUid = callerApp.info.uid;
3170            } else {
3171                Log.w(TAG, "Unable to find app for caller " + caller
3172                      + " (pid=" + callingPid + ") when starting: "
3173                      + intent.toString());
3174                err = START_PERMISSION_DENIED;
3175            }
3176        }
3177
3178        if (err != START_SUCCESS) {
3179            if (resultRecord != null) {
3180                sendActivityResultLocked(-1,
3181                    resultRecord, resultWho, requestCode,
3182                    Activity.RESULT_CANCELED, null);
3183            }
3184            return err;
3185        }
3186
3187        final int perm = checkComponentPermission(aInfo.permission, callingPid,
3188                callingUid, aInfo.exported ? -1 : aInfo.applicationInfo.uid);
3189        if (perm != PackageManager.PERMISSION_GRANTED) {
3190            if (resultRecord != null) {
3191                sendActivityResultLocked(-1,
3192                    resultRecord, resultWho, requestCode,
3193                    Activity.RESULT_CANCELED, null);
3194            }
3195            String msg = "Permission Denial: starting " + intent.toString()
3196                    + " from " + callerApp + " (pid=" + callingPid
3197                    + ", uid=" + callingUid + ")"
3198                    + " requires " + aInfo.permission;
3199            Log.w(TAG, msg);
3200            throw new SecurityException(msg);
3201        }
3202
3203        if (mController != null) {
3204            boolean abort = false;
3205            try {
3206                // The Intent we give to the watcher has the extra data
3207                // stripped off, since it can contain private information.
3208                Intent watchIntent = intent.cloneFilter();
3209                abort = !mController.activityStarting(watchIntent,
3210                        aInfo.applicationInfo.packageName);
3211            } catch (RemoteException e) {
3212                mController = null;
3213            }
3214
3215            if (abort) {
3216                if (resultRecord != null) {
3217                    sendActivityResultLocked(-1,
3218                        resultRecord, resultWho, requestCode,
3219                        Activity.RESULT_CANCELED, null);
3220                }
3221                // We pretend to the caller that it was really started, but
3222                // they will just get a cancel result.
3223                return START_SUCCESS;
3224            }
3225        }
3226
3227        HistoryRecord r = new HistoryRecord(this, callerApp, callingUid,
3228                intent, resolvedType, aInfo, mConfiguration,
3229                resultRecord, resultWho, requestCode, componentSpecified);
3230
3231        if (mResumedActivity == null
3232                || mResumedActivity.info.applicationInfo.uid != callingUid) {
3233            if (!checkAppSwitchAllowedLocked(callingPid, callingUid, "Activity start")) {
3234                PendingActivityLaunch pal = new PendingActivityLaunch();
3235                pal.r = r;
3236                pal.sourceRecord = sourceRecord;
3237                pal.grantedUriPermissions = grantedUriPermissions;
3238                pal.grantedMode = grantedMode;
3239                pal.onlyIfNeeded = onlyIfNeeded;
3240                mPendingActivityLaunches.add(pal);
3241                return START_SWITCHES_CANCELED;
3242            }
3243        }
3244
3245        if (mDidAppSwitch) {
3246            // This is the second allowed switch since we stopped switches,
3247            // so now just generally allow switches.  Use case: user presses
3248            // home (switches disabled, switch to home, mDidAppSwitch now true);
3249            // user taps a home icon (coming from home so allowed, we hit here
3250            // and now allow anyone to switch again).
3251            mAppSwitchesAllowedTime = 0;
3252        } else {
3253            mDidAppSwitch = true;
3254        }
3255
3256        doPendingActivityLaunchesLocked(false);
3257
3258        return startActivityUncheckedLocked(r, sourceRecord,
3259                grantedUriPermissions, grantedMode, onlyIfNeeded, true);
3260    }
3261
3262    private final void doPendingActivityLaunchesLocked(boolean doResume) {
3263        final int N = mPendingActivityLaunches.size();
3264        if (N <= 0) {
3265            return;
3266        }
3267        for (int i=0; i<N; i++) {
3268            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
3269            startActivityUncheckedLocked(pal.r, pal.sourceRecord,
3270                    pal.grantedUriPermissions, pal.grantedMode, pal.onlyIfNeeded,
3271                    doResume && i == (N-1));
3272        }
3273        mPendingActivityLaunches.clear();
3274    }
3275
3276    private final int startActivityUncheckedLocked(HistoryRecord r,
3277            HistoryRecord sourceRecord, Uri[] grantedUriPermissions,
3278            int grantedMode, boolean onlyIfNeeded, boolean doResume) {
3279        final Intent intent = r.intent;
3280        final int callingUid = r.launchedFromUid;
3281
3282        int launchFlags = intent.getFlags();
3283
3284        // We'll invoke onUserLeaving before onPause only if the launching
3285        // activity did not explicitly state that this is an automated launch.
3286        mUserLeaving = (launchFlags&Intent.FLAG_ACTIVITY_NO_USER_ACTION) == 0;
3287        if (DEBUG_USER_LEAVING) Log.v(TAG,
3288                "startActivity() => mUserLeaving=" + mUserLeaving);
3289
3290        // If the caller has asked not to resume at this point, we make note
3291        // of this in the record so that we can skip it when trying to find
3292        // the top running activity.
3293        if (!doResume) {
3294            r.delayedResume = true;
3295        }
3296
3297        HistoryRecord notTop = (launchFlags&Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP)
3298                != 0 ? r : null;
3299
3300        // If the onlyIfNeeded flag is set, then we can do this if the activity
3301        // being launched is the same as the one making the call...  or, as
3302        // a special case, if we do not know the caller then we count the
3303        // current top activity as the caller.
3304        if (onlyIfNeeded) {
3305            HistoryRecord checkedCaller = sourceRecord;
3306            if (checkedCaller == null) {
3307                checkedCaller = topRunningNonDelayedActivityLocked(notTop);
3308            }
3309            if (!checkedCaller.realActivity.equals(r.realActivity)) {
3310                // Caller is not the same as launcher, so always needed.
3311                onlyIfNeeded = false;
3312            }
3313        }
3314
3315        if (grantedUriPermissions != null && callingUid > 0) {
3316            for (int i=0; i<grantedUriPermissions.length; i++) {
3317                grantUriPermissionLocked(callingUid, r.packageName,
3318                        grantedUriPermissions[i], grantedMode, r);
3319            }
3320        }
3321
3322        grantUriPermissionFromIntentLocked(callingUid, r.packageName,
3323                intent, r);
3324
3325        if (sourceRecord == null) {
3326            // This activity is not being started from another...  in this
3327            // case we -always- start a new task.
3328            if ((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
3329                Log.w(TAG, "startActivity called from non-Activity context; forcing Intent.FLAG_ACTIVITY_NEW_TASK for: "
3330                      + intent);
3331                launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
3332            }
3333        } else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
3334            // The original activity who is starting us is running as a single
3335            // instance...  this new activity it is starting must go on its
3336            // own task.
3337            launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
3338        } else if (r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE
3339                || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
3340            // The activity being started is a single instance...  it always
3341            // gets launched into its own task.
3342            launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
3343        }
3344
3345        if (r.resultTo != null && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
3346            // For whatever reason this activity is being launched into a new
3347            // task...  yet the caller has requested a result back.  Well, that
3348            // is pretty messed up, so instead immediately send back a cancel
3349            // and let the new task continue launched as normal without a
3350            // dependency on its originator.
3351            Log.w(TAG, "Activity is launching as a new task, so cancelling activity result.");
3352            sendActivityResultLocked(-1,
3353                    r.resultTo, r.resultWho, r.requestCode,
3354                Activity.RESULT_CANCELED, null);
3355            r.resultTo = null;
3356        }
3357
3358        boolean addingToTask = false;
3359        if (((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0 &&
3360                (launchFlags&Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
3361                || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
3362                || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
3363            // If bring to front is requested, and no result is requested, and
3364            // we can find a task that was started with this same
3365            // component, then instead of launching bring that one to the front.
3366            if (r.resultTo == null) {
3367                // See if there is a task to bring to the front.  If this is
3368                // a SINGLE_INSTANCE activity, there can be one and only one
3369                // instance of it in the history, and it is always in its own
3370                // unique task, so we do a special search.
3371                HistoryRecord taskTop = r.launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE
3372                        ? findTaskLocked(intent, r.info)
3373                        : findActivityLocked(intent, r.info);
3374                if (taskTop != null) {
3375                    if (taskTop.task.intent == null) {
3376                        // This task was started because of movement of
3377                        // the activity based on affinity...  now that we
3378                        // are actually launching it, we can assign the
3379                        // base intent.
3380                        taskTop.task.setIntent(intent, r.info);
3381                    }
3382                    // If the target task is not in the front, then we need
3383                    // to bring it to the front...  except...  well, with
3384                    // SINGLE_TASK_LAUNCH it's not entirely clear.  We'd like
3385                    // to have the same behavior as if a new instance was
3386                    // being started, which means not bringing it to the front
3387                    // if the caller is not itself in the front.
3388                    HistoryRecord curTop = topRunningNonDelayedActivityLocked(notTop);
3389                    if (curTop.task != taskTop.task) {
3390                        r.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
3391                        boolean callerAtFront = sourceRecord == null
3392                                || curTop.task == sourceRecord.task;
3393                        if (callerAtFront) {
3394                            // We really do want to push this one into the
3395                            // user's face, right now.
3396                            moveTaskToFrontLocked(taskTop.task, r);
3397                        }
3398                    }
3399                    // If the caller has requested that the target task be
3400                    // reset, then do so.
3401                    if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
3402                        taskTop = resetTaskIfNeededLocked(taskTop, r);
3403                    }
3404                    if (onlyIfNeeded) {
3405                        // We don't need to start a new activity, and
3406                        // the client said not to do anything if that
3407                        // is the case, so this is it!  And for paranoia, make
3408                        // sure we have correctly resumed the top activity.
3409                        if (doResume) {
3410                            resumeTopActivityLocked(null);
3411                        }
3412                        return START_RETURN_INTENT_TO_CALLER;
3413                    }
3414                    if ((launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0
3415                            || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
3416                            || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
3417                        // In this situation we want to remove all activities
3418                        // from the task up to the one being started.  In most
3419                        // cases this means we are resetting the task to its
3420                        // initial state.
3421                        HistoryRecord top = performClearTaskLocked(
3422                                taskTop.task.taskId, r, launchFlags, true);
3423                        if (top != null) {
3424                            if (top.frontOfTask) {
3425                                // Activity aliases may mean we use different
3426                                // intents for the top activity, so make sure
3427                                // the task now has the identity of the new
3428                                // intent.
3429                                top.task.setIntent(r.intent, r.info);
3430                            }
3431                            logStartActivity(LOG_AM_NEW_INTENT, r, top.task);
3432                            deliverNewIntentLocked(top, r.intent);
3433                        } else {
3434                            // A special case: we need to
3435                            // start the activity because it is not currently
3436                            // running, and the caller has asked to clear the
3437                            // current task to have this activity at the top.
3438                            addingToTask = true;
3439                            // Now pretend like this activity is being started
3440                            // by the top of its task, so it is put in the
3441                            // right place.
3442                            sourceRecord = taskTop;
3443                        }
3444                    } else if (r.realActivity.equals(taskTop.task.realActivity)) {
3445                        // In this case the top activity on the task is the
3446                        // same as the one being launched, so we take that
3447                        // as a request to bring the task to the foreground.
3448                        // If the top activity in the task is the root
3449                        // activity, deliver this new intent to it if it
3450                        // desires.
3451                        if ((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
3452                                && taskTop.realActivity.equals(r.realActivity)) {
3453                            logStartActivity(LOG_AM_NEW_INTENT, r, taskTop.task);
3454                            if (taskTop.frontOfTask) {
3455                                taskTop.task.setIntent(r.intent, r.info);
3456                            }
3457                            deliverNewIntentLocked(taskTop, r.intent);
3458                        } else if (!r.intent.filterEquals(taskTop.task.intent)) {
3459                            // In this case we are launching the root activity
3460                            // of the task, but with a different intent.  We
3461                            // should start a new instance on top.
3462                            addingToTask = true;
3463                            sourceRecord = taskTop;
3464                        }
3465                    } else if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0) {
3466                        // In this case an activity is being launched in to an
3467                        // existing task, without resetting that task.  This
3468                        // is typically the situation of launching an activity
3469                        // from a notification or shortcut.  We want to place
3470                        // the new activity on top of the current task.
3471                        addingToTask = true;
3472                        sourceRecord = taskTop;
3473                    } else if (!taskTop.task.rootWasReset) {
3474                        // In this case we are launching in to an existing task
3475                        // that has not yet been started from its front door.
3476                        // The current task has been brought to the front.
3477                        // Ideally, we'd probably like to place this new task
3478                        // at the bottom of its stack, but that's a little hard
3479                        // to do with the current organization of the code so
3480                        // for now we'll just drop it.
3481                        taskTop.task.setIntent(r.intent, r.info);
3482                    }
3483                    if (!addingToTask) {
3484                        // We didn't do anything...  but it was needed (a.k.a., client
3485                        // don't use that intent!)  And for paranoia, make
3486                        // sure we have correctly resumed the top activity.
3487                        if (doResume) {
3488                            resumeTopActivityLocked(null);
3489                        }
3490                        return START_TASK_TO_FRONT;
3491                    }
3492                }
3493            }
3494        }
3495
3496        //String uri = r.intent.toURI();
3497        //Intent intent2 = new Intent(uri);
3498        //Log.i(TAG, "Given intent: " + r.intent);
3499        //Log.i(TAG, "URI is: " + uri);
3500        //Log.i(TAG, "To intent: " + intent2);
3501
3502        if (r.packageName != null) {
3503            // If the activity being launched is the same as the one currently
3504            // at the top, then we need to check if it should only be launched
3505            // once.
3506            HistoryRecord top = topRunningNonDelayedActivityLocked(notTop);
3507            if (top != null && r.resultTo == null) {
3508                if (top.realActivity.equals(r.realActivity)) {
3509                    if (top.app != null && top.app.thread != null) {
3510                        if ((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
3511                            || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP
3512                            || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
3513                            logStartActivity(LOG_AM_NEW_INTENT, top, top.task);
3514                            // For paranoia, make sure we have correctly
3515                            // resumed the top activity.
3516                            if (doResume) {
3517                                resumeTopActivityLocked(null);
3518                            }
3519                            if (onlyIfNeeded) {
3520                                // We don't need to start a new activity, and
3521                                // the client said not to do anything if that
3522                                // is the case, so this is it!
3523                                return START_RETURN_INTENT_TO_CALLER;
3524                            }
3525                            deliverNewIntentLocked(top, r.intent);
3526                            return START_DELIVERED_TO_TOP;
3527                        }
3528                    }
3529                }
3530            }
3531
3532        } else {
3533            if (r.resultTo != null) {
3534                sendActivityResultLocked(-1,
3535                        r.resultTo, r.resultWho, r.requestCode,
3536                    Activity.RESULT_CANCELED, null);
3537            }
3538            return START_CLASS_NOT_FOUND;
3539        }
3540
3541        boolean newTask = false;
3542
3543        // Should this be considered a new task?
3544        if (r.resultTo == null && !addingToTask
3545                && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
3546            // todo: should do better management of integers.
3547            mCurTask++;
3548            if (mCurTask <= 0) {
3549                mCurTask = 1;
3550            }
3551            r.task = new TaskRecord(mCurTask, r.info, intent,
3552                    (r.info.flags&ActivityInfo.FLAG_CLEAR_TASK_ON_LAUNCH) != 0);
3553            if (DEBUG_TASKS) Log.v(TAG, "Starting new activity " + r
3554                    + " in new task " + r.task);
3555            newTask = true;
3556            addRecentTask(r.task);
3557
3558        } else if (sourceRecord != null) {
3559            if (!addingToTask &&
3560                    (launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
3561                // In this case, we are adding the activity to an existing
3562                // task, but the caller has asked to clear that task if the
3563                // activity is already running.
3564                HistoryRecord top = performClearTaskLocked(
3565                        sourceRecord.task.taskId, r, launchFlags, true);
3566                if (top != null) {
3567                    logStartActivity(LOG_AM_NEW_INTENT, r, top.task);
3568                    deliverNewIntentLocked(top, r.intent);
3569                    // For paranoia, make sure we have correctly
3570                    // resumed the top activity.
3571                    if (doResume) {
3572                        resumeTopActivityLocked(null);
3573                    }
3574                    return START_DELIVERED_TO_TOP;
3575                }
3576            } else if (!addingToTask &&
3577                    (launchFlags&Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) {
3578                // In this case, we are launching an activity in our own task
3579                // that may already be running somewhere in the history, and
3580                // we want to shuffle it to the front of the stack if so.
3581                int where = findActivityInHistoryLocked(r, sourceRecord.task.taskId);
3582                if (where >= 0) {
3583                    HistoryRecord top = moveActivityToFrontLocked(where);
3584                    logStartActivity(LOG_AM_NEW_INTENT, r, top.task);
3585                    deliverNewIntentLocked(top, r.intent);
3586                    if (doResume) {
3587                        resumeTopActivityLocked(null);
3588                    }
3589                    return START_DELIVERED_TO_TOP;
3590                }
3591            }
3592            // An existing activity is starting this new activity, so we want
3593            // to keep the new one in the same task as the one that is starting
3594            // it.
3595            r.task = sourceRecord.task;
3596            if (DEBUG_TASKS) Log.v(TAG, "Starting new activity " + r
3597                    + " in existing task " + r.task);
3598
3599        } else {
3600            // This not being started from an existing activity, and not part
3601            // of a new task...  just put it in the top task, though these days
3602            // this case should never happen.
3603            final int N = mHistory.size();
3604            HistoryRecord prev =
3605                N > 0 ? (HistoryRecord)mHistory.get(N-1) : null;
3606            r.task = prev != null
3607                ? prev.task
3608                : new TaskRecord(mCurTask, r.info, intent,
3609                        (r.info.flags&ActivityInfo.FLAG_CLEAR_TASK_ON_LAUNCH) != 0);
3610            if (DEBUG_TASKS) Log.v(TAG, "Starting new activity " + r
3611                    + " in new guessed " + r.task);
3612        }
3613        if (newTask) {
3614            EventLog.writeEvent(LOG_AM_CREATE_TASK, r.task.taskId);
3615        }
3616        logStartActivity(LOG_AM_CREATE_ACTIVITY, r, r.task);
3617        startActivityLocked(r, newTask, doResume);
3618        return START_SUCCESS;
3619    }
3620
3621    public final int startActivity(IApplicationThread caller,
3622            Intent intent, String resolvedType, Uri[] grantedUriPermissions,
3623            int grantedMode, IBinder resultTo,
3624            String resultWho, int requestCode, boolean onlyIfNeeded,
3625            boolean debug) {
3626        // Refuse possible leaked file descriptors
3627        if (intent != null && intent.hasFileDescriptors()) {
3628            throw new IllegalArgumentException("File descriptors passed in Intent");
3629        }
3630
3631        final boolean componentSpecified = intent.getComponent() != null;
3632
3633        // Don't modify the client's object!
3634        intent = new Intent(intent);
3635
3636        // Collect information about the target of the Intent.
3637        ActivityInfo aInfo;
3638        try {
3639            ResolveInfo rInfo =
3640                ActivityThread.getPackageManager().resolveIntent(
3641                        intent, resolvedType,
3642                        PackageManager.MATCH_DEFAULT_ONLY
3643                        | STOCK_PM_FLAGS);
3644            aInfo = rInfo != null ? rInfo.activityInfo : null;
3645        } catch (RemoteException e) {
3646            aInfo = null;
3647        }
3648
3649        if (aInfo != null) {
3650            // Store the found target back into the intent, because now that
3651            // we have it we never want to do this again.  For example, if the
3652            // user navigates back to this point in the history, we should
3653            // always restart the exact same activity.
3654            intent.setComponent(new ComponentName(
3655                    aInfo.applicationInfo.packageName, aInfo.name));
3656
3657            // Don't debug things in the system process
3658            if (debug) {
3659                if (!aInfo.processName.equals("system")) {
3660                    setDebugApp(aInfo.processName, true, false);
3661                }
3662            }
3663        }
3664
3665        synchronized(this) {
3666            final long origId = Binder.clearCallingIdentity();
3667            int res = startActivityLocked(caller, intent, resolvedType,
3668                    grantedUriPermissions, grantedMode, aInfo,
3669                    resultTo, resultWho, requestCode, -1, -1,
3670                    onlyIfNeeded, componentSpecified);
3671            Binder.restoreCallingIdentity(origId);
3672            return res;
3673        }
3674    }
3675
3676    public int startActivityIntentSender(IApplicationThread caller,
3677            IntentSender intent, Intent fillInIntent, String resolvedType,
3678            IBinder resultTo, String resultWho, int requestCode,
3679            int flagsMask, int flagsValues) {
3680        // Refuse possible leaked file descriptors
3681        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3682            throw new IllegalArgumentException("File descriptors passed in Intent");
3683        }
3684
3685        IIntentSender sender = intent.getTarget();
3686        if (!(sender instanceof PendingIntentRecord)) {
3687            throw new IllegalArgumentException("Bad PendingIntent object");
3688        }
3689
3690        PendingIntentRecord pir = (PendingIntentRecord)sender;
3691
3692        synchronized (this) {
3693            // If this is coming from the currently resumed activity, it is
3694            // effectively saying that app switches are allowed at this point.
3695            if (mResumedActivity != null
3696                    && mResumedActivity.info.applicationInfo.uid ==
3697                            Binder.getCallingUid()) {
3698                mAppSwitchesAllowedTime = 0;
3699            }
3700        }
3701
3702        return pir.sendInner(0, fillInIntent, resolvedType,
3703                null, resultTo, resultWho, requestCode, flagsMask, flagsValues);
3704    }
3705
3706    public boolean startNextMatchingActivity(IBinder callingActivity,
3707            Intent intent) {
3708        // Refuse possible leaked file descriptors
3709        if (intent != null && intent.hasFileDescriptors() == true) {
3710            throw new IllegalArgumentException("File descriptors passed in Intent");
3711        }
3712
3713        synchronized (this) {
3714            int index = indexOfTokenLocked(callingActivity);
3715            if (index < 0) {
3716                return false;
3717            }
3718            HistoryRecord r = (HistoryRecord)mHistory.get(index);
3719            if (r.app == null || r.app.thread == null) {
3720                // The caller is not running...  d'oh!
3721                return false;
3722            }
3723            intent = new Intent(intent);
3724            // The caller is not allowed to change the data.
3725            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3726            // And we are resetting to find the next component...
3727            intent.setComponent(null);
3728
3729            ActivityInfo aInfo = null;
3730            try {
3731                List<ResolveInfo> resolves =
3732                    ActivityThread.getPackageManager().queryIntentActivities(
3733                            intent, r.resolvedType,
3734                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS);
3735
3736                // Look for the original activity in the list...
3737                final int N = resolves != null ? resolves.size() : 0;
3738                for (int i=0; i<N; i++) {
3739                    ResolveInfo rInfo = resolves.get(i);
3740                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3741                            && rInfo.activityInfo.name.equals(r.info.name)) {
3742                        // We found the current one...  the next matching is
3743                        // after it.
3744                        i++;
3745                        if (i<N) {
3746                            aInfo = resolves.get(i).activityInfo;
3747                        }
3748                        break;
3749                    }
3750                }
3751            } catch (RemoteException e) {
3752            }
3753
3754            if (aInfo == null) {
3755                // Nobody who is next!
3756                return false;
3757            }
3758
3759            intent.setComponent(new ComponentName(
3760                    aInfo.applicationInfo.packageName, aInfo.name));
3761            intent.setFlags(intent.getFlags()&~(
3762                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3763                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3764                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3765                    Intent.FLAG_ACTIVITY_NEW_TASK));
3766
3767            // Okay now we need to start the new activity, replacing the
3768            // currently running activity.  This is a little tricky because
3769            // we want to start the new one as if the current one is finished,
3770            // but not finish the current one first so that there is no flicker.
3771            // And thus...
3772            final boolean wasFinishing = r.finishing;
3773            r.finishing = true;
3774
3775            // Propagate reply information over to the new activity.
3776            final HistoryRecord resultTo = r.resultTo;
3777            final String resultWho = r.resultWho;
3778            final int requestCode = r.requestCode;
3779            r.resultTo = null;
3780            if (resultTo != null) {
3781                resultTo.removeResultsLocked(r, resultWho, requestCode);
3782            }
3783
3784            final long origId = Binder.clearCallingIdentity();
3785            // XXX we are not dealing with propagating grantedUriPermissions...
3786            // those are not yet exposed to user code, so there is no need.
3787            int res = startActivityLocked(r.app.thread, intent,
3788                    r.resolvedType, null, 0, aInfo, resultTo, resultWho,
3789                    requestCode, -1, r.launchedFromUid, false, false);
3790            Binder.restoreCallingIdentity(origId);
3791
3792            r.finishing = wasFinishing;
3793            if (res != START_SUCCESS) {
3794                return false;
3795            }
3796            return true;
3797        }
3798    }
3799
3800    public final int startActivityInPackage(int uid,
3801            Intent intent, String resolvedType, IBinder resultTo,
3802            String resultWho, int requestCode, boolean onlyIfNeeded) {
3803
3804        // This is so super not safe, that only the system (or okay root)
3805        // can do it.
3806        final int callingUid = Binder.getCallingUid();
3807        if (callingUid != 0 && callingUid != Process.myUid()) {
3808            throw new SecurityException(
3809                    "startActivityInPackage only available to the system");
3810        }
3811
3812        final boolean componentSpecified = intent.getComponent() != null;
3813
3814        // Don't modify the client's object!
3815        intent = new Intent(intent);
3816
3817        // Collect information about the target of the Intent.
3818        ActivityInfo aInfo;
3819        try {
3820            ResolveInfo rInfo =
3821                ActivityThread.getPackageManager().resolveIntent(
3822                        intent, resolvedType,
3823                        PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS);
3824            aInfo = rInfo != null ? rInfo.activityInfo : null;
3825        } catch (RemoteException e) {
3826            aInfo = null;
3827        }
3828
3829        if (aInfo != null) {
3830            // Store the found target back into the intent, because now that
3831            // we have it we never want to do this again.  For example, if the
3832            // user navigates back to this point in the history, we should
3833            // always restart the exact same activity.
3834            intent.setComponent(new ComponentName(
3835                    aInfo.applicationInfo.packageName, aInfo.name));
3836        }
3837
3838        synchronized(this) {
3839            return startActivityLocked(null, intent, resolvedType,
3840                    null, 0, aInfo, resultTo, resultWho, requestCode, -1, uid,
3841                    onlyIfNeeded, componentSpecified);
3842        }
3843    }
3844
3845    private final void addRecentTask(TaskRecord task) {
3846        // Remove any existing entries that are the same kind of task.
3847        int N = mRecentTasks.size();
3848        for (int i=0; i<N; i++) {
3849            TaskRecord tr = mRecentTasks.get(i);
3850            if ((task.affinity != null && task.affinity.equals(tr.affinity))
3851                    || (task.intent != null && task.intent.filterEquals(tr.intent))) {
3852                mRecentTasks.remove(i);
3853                i--;
3854                N--;
3855                if (task.intent == null) {
3856                    // If the new recent task we are adding is not fully
3857                    // specified, then replace it with the existing recent task.
3858                    task = tr;
3859                }
3860            }
3861        }
3862        if (N >= MAX_RECENT_TASKS) {
3863            mRecentTasks.remove(N-1);
3864        }
3865        mRecentTasks.add(0, task);
3866    }
3867
3868    public void setRequestedOrientation(IBinder token,
3869            int requestedOrientation) {
3870        synchronized (this) {
3871            int index = indexOfTokenLocked(token);
3872            if (index < 0) {
3873                return;
3874            }
3875            HistoryRecord r = (HistoryRecord)mHistory.get(index);
3876            final long origId = Binder.clearCallingIdentity();
3877            mWindowManager.setAppOrientation(r, requestedOrientation);
3878            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3879                    mConfiguration,
3880                    r.mayFreezeScreenLocked(r.app) ? r : null);
3881            if (config != null) {
3882                r.frozenBeforeDestroy = true;
3883                if (!updateConfigurationLocked(config, r)) {
3884                    resumeTopActivityLocked(null);
3885                }
3886            }
3887            Binder.restoreCallingIdentity(origId);
3888        }
3889    }
3890
3891    public int getRequestedOrientation(IBinder token) {
3892        synchronized (this) {
3893            int index = indexOfTokenLocked(token);
3894            if (index < 0) {
3895                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3896            }
3897            HistoryRecord r = (HistoryRecord)mHistory.get(index);
3898            return mWindowManager.getAppOrientation(r);
3899        }
3900    }
3901
3902    private final void stopActivityLocked(HistoryRecord r) {
3903        if (DEBUG_SWITCH) Log.d(TAG, "Stopping: " + r);
3904        if ((r.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_HISTORY) != 0
3905                || (r.info.flags&ActivityInfo.FLAG_NO_HISTORY) != 0) {
3906            if (!r.finishing) {
3907                requestFinishActivityLocked(r, Activity.RESULT_CANCELED, null,
3908                        "no-history");
3909            }
3910        } else if (r.app != null && r.app.thread != null) {
3911            if (mFocusedActivity == r) {
3912                setFocusedActivityLocked(topRunningActivityLocked(null));
3913            }
3914            r.resumeKeyDispatchingLocked();
3915            try {
3916                r.stopped = false;
3917                r.state = ActivityState.STOPPING;
3918                if (DEBUG_VISBILITY) Log.v(
3919                        TAG, "Stopping visible=" + r.visible + " for " + r);
3920                if (!r.visible) {
3921                    mWindowManager.setAppVisibility(r, false);
3922                }
3923                r.app.thread.scheduleStopActivity(r, r.visible, r.configChangeFlags);
3924            } catch (Exception e) {
3925                // Maybe just ignore exceptions here...  if the process
3926                // has crashed, our death notification will clean things
3927                // up.
3928                Log.w(TAG, "Exception thrown during pause", e);
3929                // Just in case, assume it to be stopped.
3930                r.stopped = true;
3931                r.state = ActivityState.STOPPED;
3932                if (r.configDestroy) {
3933                    destroyActivityLocked(r, true);
3934                }
3935            }
3936        }
3937    }
3938
3939    /**
3940     * @return Returns true if the activity is being finished, false if for
3941     * some reason it is being left as-is.
3942     */
3943    private final boolean requestFinishActivityLocked(IBinder token, int resultCode,
3944            Intent resultData, String reason) {
3945        if (DEBUG_RESULTS) Log.v(
3946            TAG, "Finishing activity: token=" + token
3947            + ", result=" + resultCode + ", data=" + resultData);
3948
3949        int index = indexOfTokenLocked(token);
3950        if (index < 0) {
3951            return false;
3952        }
3953        HistoryRecord r = (HistoryRecord)mHistory.get(index);
3954
3955        // Is this the last activity left?
3956        boolean lastActivity = true;
3957        for (int i=mHistory.size()-1; i>=0; i--) {
3958            HistoryRecord p = (HistoryRecord)mHistory.get(i);
3959            if (!p.finishing && p != r) {
3960                lastActivity = false;
3961                break;
3962            }
3963        }
3964
3965        // If this is the last activity, but it is the home activity, then
3966        // just don't finish it.
3967        if (lastActivity) {
3968            if (r.intent.hasCategory(Intent.CATEGORY_HOME)) {
3969                return false;
3970            }
3971        }
3972
3973        finishActivityLocked(r, index, resultCode, resultData, reason);
3974        return true;
3975    }
3976
3977    /**
3978     * @return Returns true if this activity has been removed from the history
3979     * list, or false if it is still in the list and will be removed later.
3980     */
3981    private final boolean finishActivityLocked(HistoryRecord r, int index,
3982            int resultCode, Intent resultData, String reason) {
3983        if (r.finishing) {
3984            Log.w(TAG, "Duplicate finish request for " + r);
3985            return false;
3986        }
3987
3988        r.finishing = true;
3989        EventLog.writeEvent(LOG_AM_FINISH_ACTIVITY,
3990                System.identityHashCode(r),
3991                r.task.taskId, r.shortComponentName, reason);
3992        r.task.numActivities--;
3993        if (r.frontOfTask && index < (mHistory.size()-1)) {
3994            HistoryRecord next = (HistoryRecord)mHistory.get(index+1);
3995            if (next.task == r.task) {
3996                next.frontOfTask = true;
3997            }
3998        }
3999
4000        r.pauseKeyDispatchingLocked();
4001        if (mFocusedActivity == r) {
4002            setFocusedActivityLocked(topRunningActivityLocked(null));
4003        }
4004
4005        // send the result
4006        HistoryRecord resultTo = r.resultTo;
4007        if (resultTo != null) {
4008            if (DEBUG_RESULTS) Log.v(TAG, "Adding result to " + resultTo
4009                    + " who=" + r.resultWho + " req=" + r.requestCode
4010                    + " res=" + resultCode + " data=" + resultData);
4011            if (r.info.applicationInfo.uid > 0) {
4012                grantUriPermissionFromIntentLocked(r.info.applicationInfo.uid,
4013                        r.packageName, resultData, r);
4014            }
4015            resultTo.addResultLocked(r, r.resultWho, r.requestCode, resultCode,
4016                                     resultData);
4017            r.resultTo = null;
4018        }
4019        else if (DEBUG_RESULTS) Log.v(TAG, "No result destination from " + r);
4020
4021        // Make sure this HistoryRecord is not holding on to other resources,
4022        // because clients have remote IPC references to this object so we
4023        // can't assume that will go away and want to avoid circular IPC refs.
4024        r.results = null;
4025        r.pendingResults = null;
4026        r.newIntents = null;
4027        r.icicle = null;
4028
4029        if (mPendingThumbnails.size() > 0) {
4030            // There are clients waiting to receive thumbnails so, in case
4031            // this is an activity that someone is waiting for, add it
4032            // to the pending list so we can correctly update the clients.
4033            mCancelledThumbnails.add(r);
4034        }
4035
4036        if (mResumedActivity == r) {
4037            boolean endTask = index <= 0
4038                    || ((HistoryRecord)mHistory.get(index-1)).task != r.task;
4039            if (DEBUG_TRANSITION) Log.v(TAG,
4040                    "Prepare close transition: finishing " + r);
4041            mWindowManager.prepareAppTransition(endTask
4042                    ? WindowManagerPolicy.TRANSIT_TASK_CLOSE
4043                    : WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE);
4044
4045            // Tell window manager to prepare for this one to be removed.
4046            mWindowManager.setAppVisibility(r, false);
4047
4048            if (mPausingActivity == null) {
4049                if (DEBUG_PAUSE) Log.v(TAG, "Finish needs to pause: " + r);
4050                if (DEBUG_USER_LEAVING) Log.v(TAG, "finish() => pause with userLeaving=false");
4051                startPausingLocked(false, false);
4052            }
4053
4054        } else if (r.state != ActivityState.PAUSING) {
4055            // If the activity is PAUSING, we will complete the finish once
4056            // it is done pausing; else we can just directly finish it here.
4057            if (DEBUG_PAUSE) Log.v(TAG, "Finish not pausing: " + r);
4058            return finishCurrentActivityLocked(r, index,
4059                    FINISH_AFTER_PAUSE) == null;
4060        } else {
4061            if (DEBUG_PAUSE) Log.v(TAG, "Finish waiting for pause of: " + r);
4062        }
4063
4064        return false;
4065    }
4066
4067    private static final int FINISH_IMMEDIATELY = 0;
4068    private static final int FINISH_AFTER_PAUSE = 1;
4069    private static final int FINISH_AFTER_VISIBLE = 2;
4070
4071    private final HistoryRecord finishCurrentActivityLocked(HistoryRecord r,
4072            int mode) {
4073        final int index = indexOfTokenLocked(r);
4074        if (index < 0) {
4075            return null;
4076        }
4077
4078        return finishCurrentActivityLocked(r, index, mode);
4079    }
4080
4081    private final HistoryRecord finishCurrentActivityLocked(HistoryRecord r,
4082            int index, int mode) {
4083        // First things first: if this activity is currently visible,
4084        // and the resumed activity is not yet visible, then hold off on
4085        // finishing until the resumed one becomes visible.
4086        if (mode == FINISH_AFTER_VISIBLE && r.nowVisible) {
4087            if (!mStoppingActivities.contains(r)) {
4088                mStoppingActivities.add(r);
4089                if (mStoppingActivities.size() > 3) {
4090                    // If we already have a few activities waiting to stop,
4091                    // then give up on things going idle and start clearing
4092                    // them out.
4093                    Message msg = Message.obtain();
4094                    msg.what = ActivityManagerService.IDLE_NOW_MSG;
4095                    mHandler.sendMessage(msg);
4096                }
4097            }
4098            r.state = ActivityState.STOPPING;
4099            updateOomAdjLocked();
4100            return r;
4101        }
4102
4103        // make sure the record is cleaned out of other places.
4104        mStoppingActivities.remove(r);
4105        mWaitingVisibleActivities.remove(r);
4106        if (mResumedActivity == r) {
4107            mResumedActivity = null;
4108        }
4109        final ActivityState prevState = r.state;
4110        r.state = ActivityState.FINISHING;
4111
4112        if (mode == FINISH_IMMEDIATELY
4113                || prevState == ActivityState.STOPPED
4114                || prevState == ActivityState.INITIALIZING) {
4115            // If this activity is already stopped, we can just finish
4116            // it right now.
4117            return destroyActivityLocked(r, true) ? null : r;
4118        } else {
4119            // Need to go through the full pause cycle to get this
4120            // activity into the stopped state and then finish it.
4121            if (localLOGV) Log.v(TAG, "Enqueueing pending finish: " + r);
4122            mFinishingActivities.add(r);
4123            resumeTopActivityLocked(null);
4124        }
4125        return r;
4126    }
4127
4128    /**
4129     * This is the internal entry point for handling Activity.finish().
4130     *
4131     * @param token The Binder token referencing the Activity we want to finish.
4132     * @param resultCode Result code, if any, from this Activity.
4133     * @param resultData Result data (Intent), if any, from this Activity.
4134     *
4135     * @result Returns true if the activity successfully finished, or false if it is still running.
4136     */
4137    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
4138        // Refuse possible leaked file descriptors
4139        if (resultData != null && resultData.hasFileDescriptors() == true) {
4140            throw new IllegalArgumentException("File descriptors passed in Intent");
4141        }
4142
4143        synchronized(this) {
4144            if (mController != null) {
4145                // Find the first activity that is not finishing.
4146                HistoryRecord next = topRunningActivityLocked(token, 0);
4147                if (next != null) {
4148                    // ask watcher if this is allowed
4149                    boolean resumeOK = true;
4150                    try {
4151                        resumeOK = mController.activityResuming(next.packageName);
4152                    } catch (RemoteException e) {
4153                        mController = null;
4154                    }
4155
4156                    if (!resumeOK) {
4157                        return false;
4158                    }
4159                }
4160            }
4161            final long origId = Binder.clearCallingIdentity();
4162            boolean res = requestFinishActivityLocked(token, resultCode,
4163                    resultData, "app-request");
4164            Binder.restoreCallingIdentity(origId);
4165            return res;
4166        }
4167    }
4168
4169    void sendActivityResultLocked(int callingUid, HistoryRecord r,
4170            String resultWho, int requestCode, int resultCode, Intent data) {
4171
4172        if (callingUid > 0) {
4173            grantUriPermissionFromIntentLocked(callingUid, r.packageName,
4174                    data, r);
4175        }
4176
4177        if (DEBUG_RESULTS) Log.v(TAG, "Send activity result to " + r
4178                + " : who=" + resultWho + " req=" + requestCode
4179                + " res=" + resultCode + " data=" + data);
4180        if (mResumedActivity == r && r.app != null && r.app.thread != null) {
4181            try {
4182                ArrayList<ResultInfo> list = new ArrayList<ResultInfo>();
4183                list.add(new ResultInfo(resultWho, requestCode,
4184                        resultCode, data));
4185                r.app.thread.scheduleSendResult(r, list);
4186                return;
4187            } catch (Exception e) {
4188                Log.w(TAG, "Exception thrown sending result to " + r, e);
4189            }
4190        }
4191
4192        r.addResultLocked(null, resultWho, requestCode, resultCode, data);
4193    }
4194
4195    public final void finishSubActivity(IBinder token, String resultWho,
4196            int requestCode) {
4197        synchronized(this) {
4198            int index = indexOfTokenLocked(token);
4199            if (index < 0) {
4200                return;
4201            }
4202            HistoryRecord self = (HistoryRecord)mHistory.get(index);
4203
4204            final long origId = Binder.clearCallingIdentity();
4205
4206            int i;
4207            for (i=mHistory.size()-1; i>=0; i--) {
4208                HistoryRecord r = (HistoryRecord)mHistory.get(i);
4209                if (r.resultTo == self && r.requestCode == requestCode) {
4210                    if ((r.resultWho == null && resultWho == null) ||
4211                        (r.resultWho != null && r.resultWho.equals(resultWho))) {
4212                        finishActivityLocked(r, i,
4213                                Activity.RESULT_CANCELED, null, "request-sub");
4214                    }
4215                }
4216            }
4217
4218            Binder.restoreCallingIdentity(origId);
4219        }
4220    }
4221
4222    public void overridePendingTransition(IBinder token, String packageName,
4223            int enterAnim, int exitAnim) {
4224        synchronized(this) {
4225            int index = indexOfTokenLocked(token);
4226            if (index < 0) {
4227                return;
4228            }
4229            HistoryRecord self = (HistoryRecord)mHistory.get(index);
4230
4231            final long origId = Binder.clearCallingIdentity();
4232
4233            if (self.state == ActivityState.RESUMED
4234                    || self.state == ActivityState.PAUSING) {
4235                mWindowManager.overridePendingAppTransition(packageName,
4236                        enterAnim, exitAnim);
4237            }
4238
4239            Binder.restoreCallingIdentity(origId);
4240        }
4241    }
4242
4243    /**
4244     * Perform clean-up of service connections in an activity record.
4245     */
4246    private final void cleanUpActivityServicesLocked(HistoryRecord r) {
4247        // Throw away any services that have been bound by this activity.
4248        if (r.connections != null) {
4249            Iterator<ConnectionRecord> it = r.connections.iterator();
4250            while (it.hasNext()) {
4251                ConnectionRecord c = it.next();
4252                removeConnectionLocked(c, null, r);
4253            }
4254            r.connections = null;
4255        }
4256    }
4257
4258    /**
4259     * Perform the common clean-up of an activity record.  This is called both
4260     * as part of destroyActivityLocked() (when destroying the client-side
4261     * representation) and cleaning things up as a result of its hosting
4262     * processing going away, in which case there is no remaining client-side
4263     * state to destroy so only the cleanup here is needed.
4264     */
4265    private final void cleanUpActivityLocked(HistoryRecord r, boolean cleanServices) {
4266        if (mResumedActivity == r) {
4267            mResumedActivity = null;
4268        }
4269        if (mFocusedActivity == r) {
4270            mFocusedActivity = null;
4271        }
4272
4273        r.configDestroy = false;
4274        r.frozenBeforeDestroy = false;
4275
4276        // Make sure this record is no longer in the pending finishes list.
4277        // This could happen, for example, if we are trimming activities
4278        // down to the max limit while they are still waiting to finish.
4279        mFinishingActivities.remove(r);
4280        mWaitingVisibleActivities.remove(r);
4281
4282        // Remove any pending results.
4283        if (r.finishing && r.pendingResults != null) {
4284            for (WeakReference<PendingIntentRecord> apr : r.pendingResults) {
4285                PendingIntentRecord rec = apr.get();
4286                if (rec != null) {
4287                    cancelIntentSenderLocked(rec, false);
4288                }
4289            }
4290            r.pendingResults = null;
4291        }
4292
4293        if (cleanServices) {
4294            cleanUpActivityServicesLocked(r);
4295        }
4296
4297        if (mPendingThumbnails.size() > 0) {
4298            // There are clients waiting to receive thumbnails so, in case
4299            // this is an activity that someone is waiting for, add it
4300            // to the pending list so we can correctly update the clients.
4301            mCancelledThumbnails.add(r);
4302        }
4303
4304        // Get rid of any pending idle timeouts.
4305        mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);
4306        mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
4307    }
4308
4309    private final void removeActivityFromHistoryLocked(HistoryRecord r) {
4310        if (r.state != ActivityState.DESTROYED) {
4311            mHistory.remove(r);
4312            r.inHistory = false;
4313            r.state = ActivityState.DESTROYED;
4314            mWindowManager.removeAppToken(r);
4315            if (VALIDATE_TOKENS) {
4316                mWindowManager.validateAppTokens(mHistory);
4317            }
4318            cleanUpActivityServicesLocked(r);
4319            removeActivityUriPermissionsLocked(r);
4320        }
4321    }
4322
4323    /**
4324     * Destroy the current CLIENT SIDE instance of an activity.  This may be
4325     * called both when actually finishing an activity, or when performing
4326     * a configuration switch where we destroy the current client-side object
4327     * but then create a new client-side object for this same HistoryRecord.
4328     */
4329    private final boolean destroyActivityLocked(HistoryRecord r,
4330            boolean removeFromApp) {
4331        if (DEBUG_SWITCH) Log.v(
4332            TAG, "Removing activity: token=" + r
4333              + ", app=" + (r.app != null ? r.app.processName : "(null)"));
4334        EventLog.writeEvent(LOG_AM_DESTROY_ACTIVITY,
4335                System.identityHashCode(r),
4336                r.task.taskId, r.shortComponentName);
4337
4338        boolean removedFromHistory = false;
4339
4340        cleanUpActivityLocked(r, false);
4341
4342        if (r.app != null) {
4343            if (removeFromApp) {
4344                int idx = r.app.activities.indexOf(r);
4345                if (idx >= 0) {
4346                    r.app.activities.remove(idx);
4347                }
4348                if (r.persistent) {
4349                    decPersistentCountLocked(r.app);
4350                }
4351            }
4352
4353            boolean skipDestroy = false;
4354
4355            try {
4356                if (DEBUG_SWITCH) Log.i(TAG, "Destroying: " + r);
4357                r.app.thread.scheduleDestroyActivity(r, r.finishing,
4358                        r.configChangeFlags);
4359            } catch (Exception e) {
4360                // We can just ignore exceptions here...  if the process
4361                // has crashed, our death notification will clean things
4362                // up.
4363                //Log.w(TAG, "Exception thrown during finish", e);
4364                if (r.finishing) {
4365                    removeActivityFromHistoryLocked(r);
4366                    removedFromHistory = true;
4367                    skipDestroy = true;
4368                }
4369            }
4370
4371            r.app = null;
4372            r.nowVisible = false;
4373
4374            if (r.finishing && !skipDestroy) {
4375                r.state = ActivityState.DESTROYING;
4376                Message msg = mHandler.obtainMessage(DESTROY_TIMEOUT_MSG);
4377                msg.obj = r;
4378                mHandler.sendMessageDelayed(msg, DESTROY_TIMEOUT);
4379            } else {
4380                r.state = ActivityState.DESTROYED;
4381            }
4382        } else {
4383            // remove this record from the history.
4384            if (r.finishing) {
4385                removeActivityFromHistoryLocked(r);
4386                removedFromHistory = true;
4387            } else {
4388                r.state = ActivityState.DESTROYED;
4389            }
4390        }
4391
4392        r.configChangeFlags = 0;
4393
4394        if (!mLRUActivities.remove(r)) {
4395            Log.w(TAG, "Activity " + r + " being finished, but not in LRU list");
4396        }
4397
4398        return removedFromHistory;
4399    }
4400
4401    private static void removeHistoryRecordsForAppLocked(ArrayList list,
4402                                                         ProcessRecord app)
4403    {
4404        int i = list.size();
4405        if (localLOGV) Log.v(
4406            TAG, "Removing app " + app + " from list " + list
4407            + " with " + i + " entries");
4408        while (i > 0) {
4409            i--;
4410            HistoryRecord r = (HistoryRecord)list.get(i);
4411            if (localLOGV) Log.v(
4412                TAG, "Record #" + i + " " + r + ": app=" + r.app);
4413            if (r.app == app) {
4414                if (localLOGV) Log.v(TAG, "Removing this entry!");
4415                list.remove(i);
4416            }
4417        }
4418    }
4419
4420    /**
4421     * Main function for removing an existing process from the activity manager
4422     * as a result of that process going away.  Clears out all connections
4423     * to the process.
4424     */
4425    private final void handleAppDiedLocked(ProcessRecord app,
4426            boolean restarting) {
4427        cleanUpApplicationRecordLocked(app, restarting, -1);
4428        if (!restarting) {
4429            mLRUProcesses.remove(app);
4430        }
4431
4432        // Just in case...
4433        if (mPausingActivity != null && mPausingActivity.app == app) {
4434            if (DEBUG_PAUSE) Log.v(TAG, "App died while pausing: " + mPausingActivity);
4435            mPausingActivity = null;
4436        }
4437        if (mLastPausedActivity != null && mLastPausedActivity.app == app) {
4438            mLastPausedActivity = null;
4439        }
4440
4441        // Remove this application's activities from active lists.
4442        removeHistoryRecordsForAppLocked(mLRUActivities, app);
4443        removeHistoryRecordsForAppLocked(mStoppingActivities, app);
4444        removeHistoryRecordsForAppLocked(mWaitingVisibleActivities, app);
4445        removeHistoryRecordsForAppLocked(mFinishingActivities, app);
4446
4447        boolean atTop = true;
4448        boolean hasVisibleActivities = false;
4449
4450        // Clean out the history list.
4451        int i = mHistory.size();
4452        if (localLOGV) Log.v(
4453            TAG, "Removing app " + app + " from history with " + i + " entries");
4454        while (i > 0) {
4455            i--;
4456            HistoryRecord r = (HistoryRecord)mHistory.get(i);
4457            if (localLOGV) Log.v(
4458                TAG, "Record #" + i + " " + r + ": app=" + r.app);
4459            if (r.app == app) {
4460                if ((!r.haveState && !r.stateNotNeeded) || r.finishing) {
4461                    if (localLOGV) Log.v(
4462                        TAG, "Removing this entry!  frozen=" + r.haveState
4463                        + " finishing=" + r.finishing);
4464                    mHistory.remove(i);
4465
4466                    r.inHistory = false;
4467                    mWindowManager.removeAppToken(r);
4468                    if (VALIDATE_TOKENS) {
4469                        mWindowManager.validateAppTokens(mHistory);
4470                    }
4471                    removeActivityUriPermissionsLocked(r);
4472
4473                } else {
4474                    // We have the current state for this activity, so
4475                    // it can be restarted later when needed.
4476                    if (localLOGV) Log.v(
4477                        TAG, "Keeping entry, setting app to null");
4478                    if (r.visible) {
4479                        hasVisibleActivities = true;
4480                    }
4481                    r.app = null;
4482                    r.nowVisible = false;
4483                    if (!r.haveState) {
4484                        r.icicle = null;
4485                    }
4486                }
4487
4488                cleanUpActivityLocked(r, true);
4489                r.state = ActivityState.STOPPED;
4490            }
4491            atTop = false;
4492        }
4493
4494        app.activities.clear();
4495
4496        if (app.instrumentationClass != null) {
4497            Log.w(TAG, "Crash of app " + app.processName
4498                  + " running instrumentation " + app.instrumentationClass);
4499            Bundle info = new Bundle();
4500            info.putString("shortMsg", "Process crashed.");
4501            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4502        }
4503
4504        if (!restarting) {
4505            if (!resumeTopActivityLocked(null)) {
4506                // If there was nothing to resume, and we are not already
4507                // restarting this process, but there is a visible activity that
4508                // is hosted by the process...  then make sure all visible
4509                // activities are running, taking care of restarting this
4510                // process.
4511                if (hasVisibleActivities) {
4512                    ensureActivitiesVisibleLocked(null, 0);
4513                }
4514            }
4515        }
4516    }
4517
4518    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4519        IBinder threadBinder = thread.asBinder();
4520
4521        // Find the application record.
4522        int count = mLRUProcesses.size();
4523        int i;
4524        for (i=0; i<count; i++) {
4525            ProcessRecord rec = mLRUProcesses.get(i);
4526            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4527                return i;
4528            }
4529        }
4530        return -1;
4531    }
4532
4533    private final ProcessRecord getRecordForAppLocked(
4534            IApplicationThread thread) {
4535        if (thread == null) {
4536            return null;
4537        }
4538
4539        int appIndex = getLRURecordIndexForAppLocked(thread);
4540        return appIndex >= 0 ? mLRUProcesses.get(appIndex) : null;
4541    }
4542
4543    private final void appDiedLocked(ProcessRecord app, int pid,
4544            IApplicationThread thread) {
4545
4546        mProcDeaths[0]++;
4547
4548        if (app.thread != null && app.thread.asBinder() == thread.asBinder()) {
4549            Log.i(TAG, "Process " + app.processName + " (pid " + pid
4550                    + ") has died.");
4551            EventLog.writeEvent(LOG_AM_PROCESS_DIED, app.pid, app.processName);
4552            if (localLOGV) Log.v(
4553                TAG, "Dying app: " + app + ", pid: " + pid
4554                + ", thread: " + thread.asBinder());
4555            boolean doLowMem = app.instrumentationClass == null;
4556            handleAppDiedLocked(app, false);
4557
4558            if (doLowMem) {
4559                // If there are no longer any background processes running,
4560                // and the app that died was not running instrumentation,
4561                // then tell everyone we are now low on memory.
4562                boolean haveBg = false;
4563                int count = mLRUProcesses.size();
4564                int i;
4565                for (i=0; i<count; i++) {
4566                    ProcessRecord rec = mLRUProcesses.get(i);
4567                    if (rec.thread != null && rec.setAdj >= HIDDEN_APP_MIN_ADJ) {
4568                        haveBg = true;
4569                        break;
4570                    }
4571                }
4572
4573                if (!haveBg) {
4574                    Log.i(TAG, "Low Memory: No more background processes.");
4575                    EventLog.writeEvent(LOG_AM_LOW_MEMORY, mLRUProcesses.size());
4576                    long now = SystemClock.uptimeMillis();
4577                    for (i=0; i<count; i++) {
4578                        ProcessRecord rec = mLRUProcesses.get(i);
4579                        if (rec != app && rec.thread != null &&
4580                                (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4581                            // The low memory report is overriding any current
4582                            // state for a GC request.  Make sure to do
4583                            // visible/foreground processes first.
4584                            if (rec.setAdj <= VISIBLE_APP_ADJ) {
4585                                rec.lastRequestedGc = 0;
4586                            } else {
4587                                rec.lastRequestedGc = rec.lastLowMemory;
4588                            }
4589                            rec.reportLowMemory = true;
4590                            rec.lastLowMemory = now;
4591                            mProcessesToGc.remove(rec);
4592                            addProcessToGcListLocked(rec);
4593                        }
4594                    }
4595                    scheduleAppGcsLocked();
4596                }
4597            }
4598        } else if (Config.LOGD) {
4599            Log.d(TAG, "Received spurious death notification for thread "
4600                    + thread.asBinder());
4601        }
4602    }
4603
4604    final String readFile(String filename) {
4605        try {
4606            FileInputStream fs = new FileInputStream(filename);
4607            byte[] inp = new byte[8192];
4608            int size = fs.read(inp);
4609            fs.close();
4610            return new String(inp, 0, 0, size);
4611        } catch (java.io.IOException e) {
4612        }
4613        return "";
4614    }
4615
4616    final void appNotRespondingLocked(ProcessRecord app, HistoryRecord activity,
4617            HistoryRecord reportedActivity, final String annotation) {
4618        if (app.notResponding || app.crashing) {
4619            return;
4620        }
4621
4622        // Log the ANR to the event log.
4623        EventLog.writeEvent(LOG_ANR, app.pid, app.processName, annotation);
4624
4625        // If we are on a secure build and the application is not interesting to the user (it is
4626        // not visible or in the background), just kill it instead of displaying a dialog.
4627        boolean isSecure = "1".equals(SystemProperties.get(SYSTEM_SECURE, "0"));
4628        if (isSecure && !app.isInterestingToUserLocked() && Process.myPid() != app.pid) {
4629            Process.killProcess(app.pid);
4630            return;
4631        }
4632
4633        // DeviceMonitor.start();
4634
4635        String processInfo = null;
4636        if (MONITOR_CPU_USAGE) {
4637            updateCpuStatsNow();
4638            synchronized (mProcessStatsThread) {
4639                processInfo = mProcessStats.printCurrentState();
4640            }
4641        }
4642
4643        StringBuilder info = mStringBuilder;
4644        info.setLength(0);
4645        info.append("ANR in process: ");
4646        info.append(app.processName);
4647        if (reportedActivity != null && reportedActivity.app != null) {
4648            info.append(" (last in ");
4649            info.append(reportedActivity.app.processName);
4650            info.append(")");
4651        }
4652        if (annotation != null) {
4653            info.append("\nAnnotation: ");
4654            info.append(annotation);
4655        }
4656        if (MONITOR_CPU_USAGE) {
4657            info.append("\nCPU usage:\n");
4658            info.append(processInfo);
4659        }
4660        Log.i(TAG, info.toString());
4661
4662        // The application is not responding. Dump as many thread traces as we can.
4663        boolean fileDump = prepareTraceFile(true);
4664        if (!fileDump) {
4665            // Dumping traces to the log, just dump the process that isn't responding so
4666            // we don't overflow the log
4667            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4668        } else {
4669            // Dumping traces to a file so dump all active processes we know about
4670            synchronized (this) {
4671                // First, these are the most important processes.
4672                final int[] imppids = new int[3];
4673                int i=0;
4674                imppids[0] = app.pid;
4675                i++;
4676                if (reportedActivity != null && reportedActivity.app != null
4677                        && reportedActivity.app.thread != null
4678                        && reportedActivity.app.pid != app.pid) {
4679                    imppids[i] = reportedActivity.app.pid;
4680                    i++;
4681                }
4682                imppids[i] = Process.myPid();
4683                for (i=0; i<imppids.length && imppids[i] != 0; i++) {
4684                    Process.sendSignal(imppids[i], Process.SIGNAL_QUIT);
4685                    synchronized (this) {
4686                        try {
4687                            wait(200);
4688                        } catch (InterruptedException e) {
4689                        }
4690                    }
4691                }
4692                for (i = mLRUProcesses.size() - 1 ; i >= 0 ; i--) {
4693                    ProcessRecord r = mLRUProcesses.get(i);
4694                    boolean done = false;
4695                    for (int j=0; j<imppids.length && imppids[j] != 0; j++) {
4696                        if (imppids[j] == r.pid) {
4697                            done = true;
4698                            break;
4699                        }
4700                    }
4701                    if (!done && r.thread != null) {
4702                        Process.sendSignal(r.pid, Process.SIGNAL_QUIT);
4703                        synchronized (this) {
4704                            try {
4705                                wait(200);
4706                            } catch (InterruptedException e) {
4707                            }
4708                        }
4709                    }
4710                }
4711            }
4712        }
4713
4714        if (mController != null) {
4715            try {
4716                int res = mController.appNotResponding(app.processName,
4717                        app.pid, info.toString());
4718                if (res != 0) {
4719                    if (res < 0) {
4720                        // wait until the SIGQUIT has had a chance to process before killing the
4721                        // process.
4722                        try {
4723                            wait(2000);
4724                        } catch (InterruptedException e) {
4725                        }
4726
4727                        Process.killProcess(app.pid);
4728                        return;
4729                    }
4730                }
4731            } catch (RemoteException e) {
4732                mController = null;
4733            }
4734        }
4735
4736        makeAppNotRespondingLocked(app,
4737                activity != null ? activity.shortComponentName : null,
4738                annotation != null ? "ANR " + annotation : "ANR",
4739                info.toString(), null);
4740        Message msg = Message.obtain();
4741        HashMap map = new HashMap();
4742        msg.what = SHOW_NOT_RESPONDING_MSG;
4743        msg.obj = map;
4744        map.put("app", app);
4745        if (activity != null) {
4746            map.put("activity", activity);
4747        }
4748
4749        mHandler.sendMessage(msg);
4750        return;
4751    }
4752
4753    /**
4754     * If a stack trace file has been configured, prepare the filesystem
4755     * by creating the directory if it doesn't exist and optionally
4756     * removing the old trace file.
4757     *
4758     * @param removeExisting If set, the existing trace file will be removed.
4759     * @return Returns true if the trace file preparations succeeded
4760     */
4761    public static boolean prepareTraceFile(boolean removeExisting) {
4762        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4763        boolean fileReady = false;
4764        if (!TextUtils.isEmpty(tracesPath)) {
4765            File f = new File(tracesPath);
4766            if (!f.exists()) {
4767                // Ensure the enclosing directory exists
4768                File dir = f.getParentFile();
4769                if (!dir.exists()) {
4770                    fileReady = dir.mkdirs();
4771                    FileUtils.setPermissions(dir.getAbsolutePath(),
4772                            FileUtils.S_IRWXU | FileUtils.S_IRWXG | FileUtils.S_IXOTH, -1, -1);
4773                } else if (dir.isDirectory()) {
4774                    fileReady = true;
4775                }
4776            } else if (removeExisting) {
4777                // Remove the previous traces file, so we don't fill the disk.
4778                // The VM will recreate it
4779                Log.i(TAG, "Removing old ANR trace file from " + tracesPath);
4780                fileReady = f.delete();
4781            }
4782
4783            if (removeExisting) {
4784                try {
4785                    f.createNewFile();
4786                    FileUtils.setPermissions(f.getAbsolutePath(),
4787                            FileUtils.S_IRWXU | FileUtils.S_IRWXG
4788                            | FileUtils.S_IWOTH | FileUtils.S_IROTH, -1, -1);
4789                    fileReady = true;
4790                } catch (IOException e) {
4791                    Log.w(TAG, "Unable to make ANR traces file", e);
4792                }
4793            }
4794        }
4795
4796        return fileReady;
4797    }
4798
4799
4800    private final void decPersistentCountLocked(ProcessRecord app)
4801    {
4802        app.persistentActivities--;
4803        if (app.persistentActivities > 0) {
4804            // Still more of 'em...
4805            return;
4806        }
4807        if (app.persistent) {
4808            // Ah, but the application itself is persistent.  Whatever!
4809            return;
4810        }
4811
4812        // App is no longer persistent...  make sure it and the ones
4813        // following it in the LRU list have the correc oom_adj.
4814        updateOomAdjLocked();
4815    }
4816
4817    public void setPersistent(IBinder token, boolean isPersistent) {
4818        if (checkCallingPermission(android.Manifest.permission.PERSISTENT_ACTIVITY)
4819                != PackageManager.PERMISSION_GRANTED) {
4820            String msg = "Permission Denial: setPersistent() from pid="
4821                    + Binder.getCallingPid()
4822                    + ", uid=" + Binder.getCallingUid()
4823                    + " requires " + android.Manifest.permission.PERSISTENT_ACTIVITY;
4824            Log.w(TAG, msg);
4825            throw new SecurityException(msg);
4826        }
4827
4828        synchronized(this) {
4829            int index = indexOfTokenLocked(token);
4830            if (index < 0) {
4831                return;
4832            }
4833            HistoryRecord r = (HistoryRecord)mHistory.get(index);
4834            ProcessRecord app = r.app;
4835
4836            if (localLOGV) Log.v(
4837                TAG, "Setting persistence " + isPersistent + ": " + r);
4838
4839            if (isPersistent) {
4840                if (r.persistent) {
4841                    // Okay okay, I heard you already!
4842                    if (localLOGV) Log.v(TAG, "Already persistent!");
4843                    return;
4844                }
4845                r.persistent = true;
4846                app.persistentActivities++;
4847                if (localLOGV) Log.v(TAG, "Num persistent now: " + app.persistentActivities);
4848                if (app.persistentActivities > 1) {
4849                    // We aren't the first...
4850                    if (localLOGV) Log.v(TAG, "Not the first!");
4851                    return;
4852                }
4853                if (app.persistent) {
4854                    // This would be redundant.
4855                    if (localLOGV) Log.v(TAG, "App is persistent!");
4856                    return;
4857                }
4858
4859                // App is now persistent...  make sure it and the ones
4860                // following it now have the correct oom_adj.
4861                final long origId = Binder.clearCallingIdentity();
4862                updateOomAdjLocked();
4863                Binder.restoreCallingIdentity(origId);
4864
4865            } else {
4866                if (!r.persistent) {
4867                    // Okay okay, I heard you already!
4868                    return;
4869                }
4870                r.persistent = false;
4871                final long origId = Binder.clearCallingIdentity();
4872                decPersistentCountLocked(app);
4873                Binder.restoreCallingIdentity(origId);
4874
4875            }
4876        }
4877    }
4878
4879    public boolean clearApplicationUserData(final String packageName,
4880            final IPackageDataObserver observer) {
4881        int uid = Binder.getCallingUid();
4882        int pid = Binder.getCallingPid();
4883        long callingId = Binder.clearCallingIdentity();
4884        try {
4885            IPackageManager pm = ActivityThread.getPackageManager();
4886            int pkgUid = -1;
4887            synchronized(this) {
4888                try {
4889                    pkgUid = pm.getPackageUid(packageName);
4890                } catch (RemoteException e) {
4891                }
4892                if (pkgUid == -1) {
4893                    Log.w(TAG, "Invalid packageName:" + packageName);
4894                    return false;
4895                }
4896                if (uid == pkgUid || checkComponentPermission(
4897                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4898                        pid, uid, -1)
4899                        == PackageManager.PERMISSION_GRANTED) {
4900                    restartPackageLocked(packageName, pkgUid);
4901                } else {
4902                    throw new SecurityException(pid+" does not have permission:"+
4903                            android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" +
4904                                    "for process:"+packageName);
4905                }
4906            }
4907
4908            try {
4909                //clear application user data
4910                pm.clearApplicationUserData(packageName, observer);
4911                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4912                        Uri.fromParts("package", packageName, null));
4913                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4914                broadcastIntentLocked(null, null, intent,
4915                        null, null, 0, null, null, null,
4916                        false, false, MY_PID, Process.SYSTEM_UID);
4917            } catch (RemoteException e) {
4918            }
4919        } finally {
4920            Binder.restoreCallingIdentity(callingId);
4921        }
4922        return true;
4923    }
4924
4925    public void restartPackage(final String packageName) {
4926        if (checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4927                != PackageManager.PERMISSION_GRANTED) {
4928            String msg = "Permission Denial: restartPackage() from pid="
4929                    + Binder.getCallingPid()
4930                    + ", uid=" + Binder.getCallingUid()
4931                    + " requires " + android.Manifest.permission.RESTART_PACKAGES;
4932            Log.w(TAG, msg);
4933            throw new SecurityException(msg);
4934        }
4935
4936        long callingId = Binder.clearCallingIdentity();
4937        try {
4938            IPackageManager pm = ActivityThread.getPackageManager();
4939            int pkgUid = -1;
4940            synchronized(this) {
4941                try {
4942                    pkgUid = pm.getPackageUid(packageName);
4943                } catch (RemoteException e) {
4944                }
4945                if (pkgUid == -1) {
4946                    Log.w(TAG, "Invalid packageName: " + packageName);
4947                    return;
4948                }
4949                restartPackageLocked(packageName, pkgUid);
4950            }
4951        } finally {
4952            Binder.restoreCallingIdentity(callingId);
4953        }
4954    }
4955
4956    /*
4957     * The pkg name and uid have to be specified.
4958     * @see android.app.IActivityManager#killApplicationWithUid(java.lang.String, int)
4959     */
4960    public void killApplicationWithUid(String pkg, int uid) {
4961        if (pkg == null) {
4962            return;
4963        }
4964        // Make sure the uid is valid.
4965        if (uid < 0) {
4966            Log.w(TAG, "Invalid uid specified for pkg : " + pkg);
4967            return;
4968        }
4969        int callerUid = Binder.getCallingUid();
4970        // Only the system server can kill an application
4971        if (callerUid == Process.SYSTEM_UID) {
4972            // Post an aysnc message to kill the application
4973            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4974            msg.arg1 = uid;
4975            msg.arg2 = 0;
4976            msg.obj = pkg;
4977            mHandler.sendMessage(msg);
4978        } else {
4979            throw new SecurityException(callerUid + " cannot kill pkg: " +
4980                    pkg);
4981        }
4982    }
4983
4984    public void closeSystemDialogs(String reason) {
4985        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4986        if (reason != null) {
4987            intent.putExtra("reason", reason);
4988        }
4989
4990        final int uid = Binder.getCallingUid();
4991        final long origId = Binder.clearCallingIdentity();
4992        synchronized (this) {
4993            int i = mWatchers.beginBroadcast();
4994            while (i > 0) {
4995                i--;
4996                IActivityWatcher w = mWatchers.getBroadcastItem(i);
4997                if (w != null) {
4998                    try {
4999                        w.closingSystemDialogs(reason);
5000                    } catch (RemoteException e) {
5001                    }
5002                }
5003            }
5004            mWatchers.finishBroadcast();
5005
5006            mWindowManager.closeSystemDialogs(reason);
5007
5008            for (i=mHistory.size()-1; i>=0; i--) {
5009                HistoryRecord r = (HistoryRecord)mHistory.get(i);
5010                if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
5011                    finishActivityLocked(r, i,
5012                            Activity.RESULT_CANCELED, null, "close-sys");
5013                }
5014            }
5015
5016            broadcastIntentLocked(null, null, intent, null,
5017                    null, 0, null, null, null, false, false, -1, uid);
5018        }
5019        Binder.restoreCallingIdentity(origId);
5020    }
5021
5022    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
5023            throws RemoteException {
5024        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5025        for (int i=pids.length-1; i>=0; i--) {
5026            infos[i] = new Debug.MemoryInfo();
5027            Debug.getMemoryInfo(pids[i], infos[i]);
5028        }
5029        return infos;
5030    }
5031
5032    public void killApplicationProcess(String processName, int uid) {
5033        if (processName == null) {
5034            return;
5035        }
5036
5037        int callerUid = Binder.getCallingUid();
5038        // Only the system server can kill an application
5039        if (callerUid == Process.SYSTEM_UID) {
5040            synchronized (this) {
5041                ProcessRecord app = getProcessRecordLocked(processName, uid);
5042                if (app != null) {
5043                    try {
5044                        app.thread.scheduleSuicide();
5045                    } catch (RemoteException e) {
5046                        // If the other end already died, then our work here is done.
5047                    }
5048                } else {
5049                    Log.w(TAG, "Process/uid not found attempting kill of "
5050                            + processName + " / " + uid);
5051                }
5052            }
5053        } else {
5054            throw new SecurityException(callerUid + " cannot kill app process: " +
5055                    processName);
5056        }
5057    }
5058
5059    private void restartPackageLocked(final String packageName, int uid) {
5060        uninstallPackageLocked(packageName, uid, false);
5061        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5062                Uri.fromParts("package", packageName, null));
5063        intent.putExtra(Intent.EXTRA_UID, uid);
5064        broadcastIntentLocked(null, null, intent,
5065                null, null, 0, null, null, null,
5066                false, false, MY_PID, Process.SYSTEM_UID);
5067    }
5068
5069    private final void uninstallPackageLocked(String name, int uid,
5070            boolean callerWillRestart) {
5071        if (Config.LOGD) Log.d(TAG, "Uninstalling process " + name);
5072
5073        int i, N;
5074
5075        final String procNamePrefix = name + ":";
5076        if (uid < 0) {
5077            try {
5078                uid = ActivityThread.getPackageManager().getPackageUid(name);
5079            } catch (RemoteException e) {
5080            }
5081        }
5082
5083        Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator();
5084        while (badApps.hasNext()) {
5085            SparseArray<Long> ba = badApps.next();
5086            if (ba.get(uid) != null) {
5087                badApps.remove();
5088            }
5089        }
5090
5091        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5092
5093        // Remove all processes this package may have touched: all with the
5094        // same UID (except for the system or root user), and all whose name
5095        // matches the package name.
5096        for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
5097            final int NA = apps.size();
5098            for (int ia=0; ia<NA; ia++) {
5099                ProcessRecord app = apps.valueAt(ia);
5100                if (app.removed) {
5101                    procs.add(app);
5102                } else if ((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid)
5103                        || app.processName.equals(name)
5104                        || app.processName.startsWith(procNamePrefix)) {
5105                    app.removed = true;
5106                    procs.add(app);
5107                }
5108            }
5109        }
5110
5111        N = procs.size();
5112        for (i=0; i<N; i++) {
5113            removeProcessLocked(procs.get(i), callerWillRestart);
5114        }
5115
5116        for (i=mHistory.size()-1; i>=0; i--) {
5117            HistoryRecord r = (HistoryRecord)mHistory.get(i);
5118            if (r.packageName.equals(name)) {
5119                if (Config.LOGD) Log.d(
5120                    TAG, "  Force finishing activity "
5121                    + r.intent.getComponent().flattenToShortString());
5122                if (r.app != null) {
5123                    r.app.removed = true;
5124                }
5125                r.app = null;
5126                finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "uninstall");
5127            }
5128        }
5129
5130        ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
5131        for (ServiceRecord service : mServices.values()) {
5132            if (service.packageName.equals(name)) {
5133                if (service.app != null) {
5134                    service.app.removed = true;
5135                }
5136                service.app = null;
5137                services.add(service);
5138            }
5139        }
5140
5141        N = services.size();
5142        for (i=0; i<N; i++) {
5143            bringDownServiceLocked(services.get(i), true);
5144        }
5145
5146        resumeTopActivityLocked(null);
5147    }
5148
5149    private final boolean removeProcessLocked(ProcessRecord app, boolean callerWillRestart) {
5150        final String name = app.processName;
5151        final int uid = app.info.uid;
5152        if (Config.LOGD) Log.d(
5153            TAG, "Force removing process " + app + " (" + name
5154            + "/" + uid + ")");
5155
5156        mProcessNames.remove(name, uid);
5157        boolean needRestart = false;
5158        if (app.pid > 0 && app.pid != MY_PID) {
5159            int pid = app.pid;
5160            synchronized (mPidsSelfLocked) {
5161                mPidsSelfLocked.remove(pid);
5162                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5163            }
5164            handleAppDiedLocked(app, true);
5165            mLRUProcesses.remove(app);
5166            Process.killProcess(pid);
5167
5168            if (app.persistent) {
5169                if (!callerWillRestart) {
5170                    addAppLocked(app.info);
5171                } else {
5172                    needRestart = true;
5173                }
5174            }
5175        } else {
5176            mRemovedProcesses.add(app);
5177        }
5178
5179        return needRestart;
5180    }
5181
5182    private final void processStartTimedOutLocked(ProcessRecord app) {
5183        final int pid = app.pid;
5184        boolean gone = false;
5185        synchronized (mPidsSelfLocked) {
5186            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5187            if (knownApp != null && knownApp.thread == null) {
5188                mPidsSelfLocked.remove(pid);
5189                gone = true;
5190            }
5191        }
5192
5193        if (gone) {
5194            Log.w(TAG, "Process " + app + " failed to attach");
5195            mProcessNames.remove(app.processName, app.info.uid);
5196            Process.killProcess(pid);
5197            if (mPendingBroadcast != null && mPendingBroadcast.curApp.pid == pid) {
5198                Log.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5199                mPendingBroadcast = null;
5200                scheduleBroadcastsLocked();
5201            }
5202            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5203                Log.w(TAG, "Unattached app died before backup, skipping");
5204                try {
5205                    IBackupManager bm = IBackupManager.Stub.asInterface(
5206                            ServiceManager.getService(Context.BACKUP_SERVICE));
5207                    bm.agentDisconnected(app.info.packageName);
5208                } catch (RemoteException e) {
5209                    // Can't happen; the backup manager is local
5210                }
5211            }
5212        } else {
5213            Log.w(TAG, "Spurious process start timeout - pid not known for " + app);
5214        }
5215    }
5216
5217    private final boolean attachApplicationLocked(IApplicationThread thread,
5218            int pid) {
5219
5220        // Find the application record that is being attached...  either via
5221        // the pid if we are running in multiple processes, or just pull the
5222        // next app record if we are emulating process with anonymous threads.
5223        ProcessRecord app;
5224        if (pid != MY_PID && pid >= 0) {
5225            synchronized (mPidsSelfLocked) {
5226                app = mPidsSelfLocked.get(pid);
5227            }
5228        } else if (mStartingProcesses.size() > 0) {
5229            app = mStartingProcesses.remove(0);
5230            app.setPid(pid);
5231        } else {
5232            app = null;
5233        }
5234
5235        if (app == null) {
5236            Log.w(TAG, "No pending application record for pid " + pid
5237                    + " (IApplicationThread " + thread + "); dropping process");
5238            EventLog.writeEvent(LOG_AM_DROP_PROCESS, pid);
5239            if (pid > 0 && pid != MY_PID) {
5240                Process.killProcess(pid);
5241            } else {
5242                try {
5243                    thread.scheduleExit();
5244                } catch (Exception e) {
5245                    // Ignore exceptions.
5246                }
5247            }
5248            return false;
5249        }
5250
5251        // If this application record is still attached to a previous
5252        // process, clean it up now.
5253        if (app.thread != null) {
5254            handleAppDiedLocked(app, true);
5255        }
5256
5257        // Tell the process all about itself.
5258
5259        if (localLOGV) Log.v(
5260                TAG, "Binding process pid " + pid + " to record " + app);
5261
5262        String processName = app.processName;
5263        try {
5264            thread.asBinder().linkToDeath(new AppDeathRecipient(
5265                    app, pid, thread), 0);
5266        } catch (RemoteException e) {
5267            app.resetPackageList();
5268            startProcessLocked(app, "link fail", processName);
5269            return false;
5270        }
5271
5272        EventLog.writeEvent(LOG_AM_PROCESS_BOUND, app.pid, app.processName);
5273
5274        app.thread = thread;
5275        app.curAdj = app.setAdj = -100;
5276        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5277        app.forcingToForeground = null;
5278        app.foregroundServices = false;
5279        app.debugging = false;
5280
5281        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5282
5283        boolean normalMode = mSystemReady || isAllowedWhileBooting(app.info);
5284        List providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5285
5286        if (!normalMode) {
5287            Log.i(TAG, "Launching preboot mode app: " + app);
5288        }
5289
5290        if (localLOGV) Log.v(
5291            TAG, "New app record " + app
5292            + " thread=" + thread.asBinder() + " pid=" + pid);
5293        try {
5294            int testMode = IApplicationThread.DEBUG_OFF;
5295            if (mDebugApp != null && mDebugApp.equals(processName)) {
5296                testMode = mWaitForDebugger
5297                    ? IApplicationThread.DEBUG_WAIT
5298                    : IApplicationThread.DEBUG_ON;
5299                app.debugging = true;
5300                if (mDebugTransient) {
5301                    mDebugApp = mOrigDebugApp;
5302                    mWaitForDebugger = mOrigWaitForDebugger;
5303                }
5304            }
5305
5306            // If the app is being launched for restore or full backup, set it up specially
5307            boolean isRestrictedBackupMode = false;
5308            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5309                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5310                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5311            }
5312
5313            ensurePackageDexOpt(app.instrumentationInfo != null
5314                    ? app.instrumentationInfo.packageName
5315                    : app.info.packageName);
5316            if (app.instrumentationClass != null) {
5317                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5318            }
5319            if (DEBUG_CONFIGURATION) Log.v(TAG, "Binding proc "
5320                    + processName + " with config " + mConfiguration);
5321            thread.bindApplication(processName, app.instrumentationInfo != null
5322                    ? app.instrumentationInfo : app.info, providers,
5323                    app.instrumentationClass, app.instrumentationProfileFile,
5324                    app.instrumentationArguments, app.instrumentationWatcher, testMode,
5325                    isRestrictedBackupMode || !normalMode,
5326                    mConfiguration, getCommonServicesLocked());
5327            updateLRUListLocked(app, false);
5328            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5329        } catch (Exception e) {
5330            // todo: Yikes!  What should we do?  For now we will try to
5331            // start another process, but that could easily get us in
5332            // an infinite loop of restarting processes...
5333            Log.w(TAG, "Exception thrown during bind!", e);
5334
5335            app.resetPackageList();
5336            startProcessLocked(app, "bind fail", processName);
5337            return false;
5338        }
5339
5340        // Remove this record from the list of starting applications.
5341        mPersistentStartingProcesses.remove(app);
5342        mProcessesOnHold.remove(app);
5343
5344        boolean badApp = false;
5345        boolean didSomething = false;
5346
5347        // See if the top visible activity is waiting to run in this process...
5348        HistoryRecord hr = topRunningActivityLocked(null);
5349        if (hr != null) {
5350            if (hr.app == null && app.info.uid == hr.info.applicationInfo.uid
5351                    && processName.equals(hr.processName)) {
5352                try {
5353                    if (realStartActivityLocked(hr, app, true, true)) {
5354                        didSomething = true;
5355                    }
5356                } catch (Exception e) {
5357                    Log.w(TAG, "Exception in new application when starting activity "
5358                          + hr.intent.getComponent().flattenToShortString(), e);
5359                    badApp = true;
5360                }
5361            } else {
5362                ensureActivitiesVisibleLocked(hr, null, processName, 0);
5363            }
5364        }
5365
5366        // Find any services that should be running in this process...
5367        if (!badApp && mPendingServices.size() > 0) {
5368            ServiceRecord sr = null;
5369            try {
5370                for (int i=0; i<mPendingServices.size(); i++) {
5371                    sr = mPendingServices.get(i);
5372                    if (app.info.uid != sr.appInfo.uid
5373                            || !processName.equals(sr.processName)) {
5374                        continue;
5375                    }
5376
5377                    mPendingServices.remove(i);
5378                    i--;
5379                    realStartServiceLocked(sr, app);
5380                    didSomething = true;
5381                }
5382            } catch (Exception e) {
5383                Log.w(TAG, "Exception in new application when starting service "
5384                      + sr.shortName, e);
5385                badApp = true;
5386            }
5387        }
5388
5389        // Check if the next broadcast receiver is in this process...
5390        BroadcastRecord br = mPendingBroadcast;
5391        if (!badApp && br != null && br.curApp == app) {
5392            try {
5393                mPendingBroadcast = null;
5394                processCurBroadcastLocked(br, app);
5395                didSomething = true;
5396            } catch (Exception e) {
5397                Log.w(TAG, "Exception in new application when starting receiver "
5398                      + br.curComponent.flattenToShortString(), e);
5399                badApp = true;
5400                logBroadcastReceiverDiscard(br);
5401                finishReceiverLocked(br.receiver, br.resultCode, br.resultData,
5402                        br.resultExtras, br.resultAbort, true);
5403                scheduleBroadcastsLocked();
5404            }
5405        }
5406
5407        // Check whether the next backup agent is in this process...
5408        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.info.uid) {
5409            if (DEBUG_BACKUP) Log.v(TAG, "New app is backup target, launching agent for " + app);
5410            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5411            try {
5412                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, mBackupTarget.backupMode);
5413            } catch (Exception e) {
5414                Log.w(TAG, "Exception scheduling backup agent creation: ");
5415                e.printStackTrace();
5416            }
5417        }
5418
5419        if (badApp) {
5420            // todo: Also need to kill application to deal with all
5421            // kinds of exceptions.
5422            handleAppDiedLocked(app, false);
5423            return false;
5424        }
5425
5426        if (!didSomething) {
5427            updateOomAdjLocked();
5428        }
5429
5430        return true;
5431    }
5432
5433    public final void attachApplication(IApplicationThread thread) {
5434        synchronized (this) {
5435            int callingPid = Binder.getCallingPid();
5436            final long origId = Binder.clearCallingIdentity();
5437            attachApplicationLocked(thread, callingPid);
5438            Binder.restoreCallingIdentity(origId);
5439        }
5440    }
5441
5442    public final void activityIdle(IBinder token, Configuration config) {
5443        final long origId = Binder.clearCallingIdentity();
5444        activityIdleInternal(token, false, config);
5445        Binder.restoreCallingIdentity(origId);
5446    }
5447
5448    final ArrayList<HistoryRecord> processStoppingActivitiesLocked(
5449            boolean remove) {
5450        int N = mStoppingActivities.size();
5451        if (N <= 0) return null;
5452
5453        ArrayList<HistoryRecord> stops = null;
5454
5455        final boolean nowVisible = mResumedActivity != null
5456                && mResumedActivity.nowVisible
5457                && !mResumedActivity.waitingVisible;
5458        for (int i=0; i<N; i++) {
5459            HistoryRecord s = mStoppingActivities.get(i);
5460            if (localLOGV) Log.v(TAG, "Stopping " + s + ": nowVisible="
5461                    + nowVisible + " waitingVisible=" + s.waitingVisible
5462                    + " finishing=" + s.finishing);
5463            if (s.waitingVisible && nowVisible) {
5464                mWaitingVisibleActivities.remove(s);
5465                s.waitingVisible = false;
5466                if (s.finishing) {
5467                    // If this activity is finishing, it is sitting on top of
5468                    // everyone else but we now know it is no longer needed...
5469                    // so get rid of it.  Otherwise, we need to go through the
5470                    // normal flow and hide it once we determine that it is
5471                    // hidden by the activities in front of it.
5472                    if (localLOGV) Log.v(TAG, "Before stopping, can hide: " + s);
5473                    mWindowManager.setAppVisibility(s, false);
5474                }
5475            }
5476            if (!s.waitingVisible && remove) {
5477                if (localLOGV) Log.v(TAG, "Ready to stop: " + s);
5478                if (stops == null) {
5479                    stops = new ArrayList<HistoryRecord>();
5480                }
5481                stops.add(s);
5482                mStoppingActivities.remove(i);
5483                N--;
5484                i--;
5485            }
5486        }
5487
5488        return stops;
5489    }
5490
5491    void enableScreenAfterBoot() {
5492        EventLog.writeEvent(LOG_BOOT_PROGRESS_ENABLE_SCREEN,
5493                SystemClock.uptimeMillis());
5494        mWindowManager.enableScreenAfterBoot();
5495    }
5496
5497    final void activityIdleInternal(IBinder token, boolean fromTimeout,
5498            Configuration config) {
5499        if (localLOGV) Log.v(TAG, "Activity idle: " + token);
5500
5501        ArrayList<HistoryRecord> stops = null;
5502        ArrayList<HistoryRecord> finishes = null;
5503        ArrayList<HistoryRecord> thumbnails = null;
5504        int NS = 0;
5505        int NF = 0;
5506        int NT = 0;
5507        IApplicationThread sendThumbnail = null;
5508        boolean booting = false;
5509        boolean enableScreen = false;
5510
5511        synchronized (this) {
5512            if (token != null) {
5513                mHandler.removeMessages(IDLE_TIMEOUT_MSG, token);
5514            }
5515
5516            // Get the activity record.
5517            int index = indexOfTokenLocked(token);
5518            if (index >= 0) {
5519                HistoryRecord r = (HistoryRecord)mHistory.get(index);
5520
5521                // This is a hack to semi-deal with a race condition
5522                // in the client where it can be constructed with a
5523                // newer configuration from when we asked it to launch.
5524                // We'll update with whatever configuration it now says
5525                // it used to launch.
5526                if (config != null) {
5527                    r.configuration = config;
5528                }
5529
5530                // No longer need to keep the device awake.
5531                if (mResumedActivity == r && mLaunchingActivity.isHeld()) {
5532                    mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
5533                    mLaunchingActivity.release();
5534                }
5535
5536                // We are now idle.  If someone is waiting for a thumbnail from
5537                // us, we can now deliver.
5538                r.idle = true;
5539                scheduleAppGcsLocked();
5540                if (r.thumbnailNeeded && r.app != null && r.app.thread != null) {
5541                    sendThumbnail = r.app.thread;
5542                    r.thumbnailNeeded = false;
5543                }
5544
5545                // If this activity is fullscreen, set up to hide those under it.
5546
5547                if (DEBUG_VISBILITY) Log.v(TAG, "Idle activity for " + r);
5548                ensureActivitiesVisibleLocked(null, 0);
5549
5550                //Log.i(TAG, "IDLE: mBooted=" + mBooted + ", fromTimeout=" + fromTimeout);
5551                if (!mBooted && !fromTimeout) {
5552                    mBooted = true;
5553                    enableScreen = true;
5554                }
5555            }
5556
5557            // Atomically retrieve all of the other things to do.
5558            stops = processStoppingActivitiesLocked(true);
5559            NS = stops != null ? stops.size() : 0;
5560            if ((NF=mFinishingActivities.size()) > 0) {
5561                finishes = new ArrayList<HistoryRecord>(mFinishingActivities);
5562                mFinishingActivities.clear();
5563            }
5564            if ((NT=mCancelledThumbnails.size()) > 0) {
5565                thumbnails = new ArrayList<HistoryRecord>(mCancelledThumbnails);
5566                mCancelledThumbnails.clear();
5567            }
5568
5569            booting = mBooting;
5570            mBooting = false;
5571        }
5572
5573        int i;
5574
5575        // Send thumbnail if requested.
5576        if (sendThumbnail != null) {
5577            try {
5578                sendThumbnail.requestThumbnail(token);
5579            } catch (Exception e) {
5580                Log.w(TAG, "Exception thrown when requesting thumbnail", e);
5581                sendPendingThumbnail(null, token, null, null, true);
5582            }
5583        }
5584
5585        // Stop any activities that are scheduled to do so but have been
5586        // waiting for the next one to start.
5587        for (i=0; i<NS; i++) {
5588            HistoryRecord r = (HistoryRecord)stops.get(i);
5589            synchronized (this) {
5590                if (r.finishing) {
5591                    finishCurrentActivityLocked(r, FINISH_IMMEDIATELY);
5592                } else {
5593                    stopActivityLocked(r);
5594                }
5595            }
5596        }
5597
5598        // Finish any activities that are scheduled to do so but have been
5599        // waiting for the next one to start.
5600        for (i=0; i<NF; i++) {
5601            HistoryRecord r = (HistoryRecord)finishes.get(i);
5602            synchronized (this) {
5603                destroyActivityLocked(r, true);
5604            }
5605        }
5606
5607        // Report back to any thumbnail receivers.
5608        for (i=0; i<NT; i++) {
5609            HistoryRecord r = (HistoryRecord)thumbnails.get(i);
5610            sendPendingThumbnail(r, null, null, null, true);
5611        }
5612
5613        if (booting) {
5614            finishBooting();
5615        }
5616
5617        trimApplications();
5618        //dump();
5619        //mWindowManager.dump();
5620
5621        if (enableScreen) {
5622            enableScreenAfterBoot();
5623        }
5624    }
5625
5626    final void finishBooting() {
5627        // Ensure that any processes we had put on hold are now started
5628        // up.
5629        final int NP = mProcessesOnHold.size();
5630        if (NP > 0) {
5631            ArrayList<ProcessRecord> procs =
5632                new ArrayList<ProcessRecord>(mProcessesOnHold);
5633            for (int ip=0; ip<NP; ip++) {
5634                this.startProcessLocked(procs.get(ip), "on-hold", null);
5635            }
5636        }
5637        if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
5638            // Tell anyone interested that we are done booting!
5639            synchronized (this) {
5640                broadcastIntentLocked(null, null,
5641                        new Intent(Intent.ACTION_BOOT_COMPLETED, null),
5642                        null, null, 0, null, null,
5643                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5644                        false, false, MY_PID, Process.SYSTEM_UID);
5645            }
5646        }
5647    }
5648
5649    final void ensureBootCompleted() {
5650        boolean booting;
5651        boolean enableScreen;
5652        synchronized (this) {
5653            booting = mBooting;
5654            mBooting = false;
5655            enableScreen = !mBooted;
5656            mBooted = true;
5657        }
5658
5659        if (booting) {
5660            finishBooting();
5661        }
5662
5663        if (enableScreen) {
5664            enableScreenAfterBoot();
5665        }
5666    }
5667
5668    public final void activityPaused(IBinder token, Bundle icicle) {
5669        // Refuse possible leaked file descriptors
5670        if (icicle != null && icicle.hasFileDescriptors()) {
5671            throw new IllegalArgumentException("File descriptors passed in Bundle");
5672        }
5673
5674        final long origId = Binder.clearCallingIdentity();
5675        activityPaused(token, icicle, false);
5676        Binder.restoreCallingIdentity(origId);
5677    }
5678
5679    final void activityPaused(IBinder token, Bundle icicle, boolean timeout) {
5680        if (DEBUG_PAUSE) Log.v(
5681            TAG, "Activity paused: token=" + token + ", icicle=" + icicle
5682            + ", timeout=" + timeout);
5683
5684        HistoryRecord r = null;
5685
5686        synchronized (this) {
5687            int index = indexOfTokenLocked(token);
5688            if (index >= 0) {
5689                r = (HistoryRecord)mHistory.get(index);
5690                if (!timeout) {
5691                    r.icicle = icicle;
5692                    r.haveState = true;
5693                }
5694                mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);
5695                if (mPausingActivity == r) {
5696                    r.state = ActivityState.PAUSED;
5697                    completePauseLocked();
5698                } else {
5699                	EventLog.writeEvent(LOG_AM_FAILED_TO_PAUSE_ACTIVITY,
5700                	        System.identityHashCode(r), r.shortComponentName,
5701                			mPausingActivity != null
5702                			    ? mPausingActivity.shortComponentName : "(none)");
5703                }
5704            }
5705        }
5706    }
5707
5708    public final void activityStopped(IBinder token, Bitmap thumbnail,
5709            CharSequence description) {
5710        if (localLOGV) Log.v(
5711            TAG, "Activity stopped: token=" + token);
5712
5713        HistoryRecord r = null;
5714
5715        final long origId = Binder.clearCallingIdentity();
5716
5717        synchronized (this) {
5718            int index = indexOfTokenLocked(token);
5719            if (index >= 0) {
5720                r = (HistoryRecord)mHistory.get(index);
5721                r.thumbnail = thumbnail;
5722                r.description = description;
5723                r.stopped = true;
5724                r.state = ActivityState.STOPPED;
5725                if (!r.finishing) {
5726                    if (r.configDestroy) {
5727                        destroyActivityLocked(r, true);
5728                        resumeTopActivityLocked(null);
5729                    }
5730                }
5731            }
5732        }
5733
5734        if (r != null) {
5735            sendPendingThumbnail(r, null, null, null, false);
5736        }
5737
5738        trimApplications();
5739
5740        Binder.restoreCallingIdentity(origId);
5741    }
5742
5743    public final void activityDestroyed(IBinder token) {
5744        if (DEBUG_SWITCH) Log.v(TAG, "ACTIVITY DESTROYED: " + token);
5745        synchronized (this) {
5746            mHandler.removeMessages(DESTROY_TIMEOUT_MSG, token);
5747
5748            int index = indexOfTokenLocked(token);
5749            if (index >= 0) {
5750                HistoryRecord r = (HistoryRecord)mHistory.get(index);
5751                if (r.state == ActivityState.DESTROYING) {
5752                    final long origId = Binder.clearCallingIdentity();
5753                    removeActivityFromHistoryLocked(r);
5754                    Binder.restoreCallingIdentity(origId);
5755                }
5756            }
5757        }
5758    }
5759
5760    public String getCallingPackage(IBinder token) {
5761        synchronized (this) {
5762            HistoryRecord r = getCallingRecordLocked(token);
5763            return r != null && r.app != null ? r.info.packageName : null;
5764        }
5765    }
5766
5767    public ComponentName getCallingActivity(IBinder token) {
5768        synchronized (this) {
5769            HistoryRecord r = getCallingRecordLocked(token);
5770            return r != null ? r.intent.getComponent() : null;
5771        }
5772    }
5773
5774    private HistoryRecord getCallingRecordLocked(IBinder token) {
5775        int index = indexOfTokenLocked(token);
5776        if (index >= 0) {
5777            HistoryRecord r = (HistoryRecord)mHistory.get(index);
5778            if (r != null) {
5779                return r.resultTo;
5780            }
5781        }
5782        return null;
5783    }
5784
5785    public ComponentName getActivityClassForToken(IBinder token) {
5786        synchronized(this) {
5787            int index = indexOfTokenLocked(token);
5788            if (index >= 0) {
5789                HistoryRecord r = (HistoryRecord)mHistory.get(index);
5790                return r.intent.getComponent();
5791            }
5792            return null;
5793        }
5794    }
5795
5796    public String getPackageForToken(IBinder token) {
5797        synchronized(this) {
5798            int index = indexOfTokenLocked(token);
5799            if (index >= 0) {
5800                HistoryRecord r = (HistoryRecord)mHistory.get(index);
5801                return r.packageName;
5802            }
5803            return null;
5804        }
5805    }
5806
5807    public IIntentSender getIntentSender(int type,
5808            String packageName, IBinder token, String resultWho,
5809            int requestCode, Intent intent, String resolvedType, int flags) {
5810        // Refuse possible leaked file descriptors
5811        if (intent != null && intent.hasFileDescriptors() == true) {
5812            throw new IllegalArgumentException("File descriptors passed in Intent");
5813        }
5814
5815        if (type == INTENT_SENDER_BROADCAST) {
5816            if ((intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5817                throw new IllegalArgumentException(
5818                        "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5819            }
5820        }
5821
5822        synchronized(this) {
5823            int callingUid = Binder.getCallingUid();
5824            try {
5825                if (callingUid != 0 && callingUid != Process.SYSTEM_UID &&
5826                        Process.supportsProcesses()) {
5827                    int uid = ActivityThread.getPackageManager()
5828                            .getPackageUid(packageName);
5829                    if (uid != Binder.getCallingUid()) {
5830                        String msg = "Permission Denial: getIntentSender() from pid="
5831                            + Binder.getCallingPid()
5832                            + ", uid=" + Binder.getCallingUid()
5833                            + ", (need uid=" + uid + ")"
5834                            + " is not allowed to send as package " + packageName;
5835                        Log.w(TAG, msg);
5836                        throw new SecurityException(msg);
5837                    }
5838                }
5839            } catch (RemoteException e) {
5840                throw new SecurityException(e);
5841            }
5842            HistoryRecord activity = null;
5843            if (type == INTENT_SENDER_ACTIVITY_RESULT) {
5844                int index = indexOfTokenLocked(token);
5845                if (index < 0) {
5846                    return null;
5847                }
5848                activity = (HistoryRecord)mHistory.get(index);
5849                if (activity.finishing) {
5850                    return null;
5851                }
5852            }
5853
5854            final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5855            final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5856            final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5857            flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5858                    |PendingIntent.FLAG_UPDATE_CURRENT);
5859
5860            PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5861                    type, packageName, activity, resultWho,
5862                    requestCode, intent, resolvedType, flags);
5863            WeakReference<PendingIntentRecord> ref;
5864            ref = mIntentSenderRecords.get(key);
5865            PendingIntentRecord rec = ref != null ? ref.get() : null;
5866            if (rec != null) {
5867                if (!cancelCurrent) {
5868                    if (updateCurrent) {
5869                        rec.key.requestIntent.replaceExtras(intent);
5870                    }
5871                    return rec;
5872                }
5873                rec.canceled = true;
5874                mIntentSenderRecords.remove(key);
5875            }
5876            if (noCreate) {
5877                return rec;
5878            }
5879            rec = new PendingIntentRecord(this, key, callingUid);
5880            mIntentSenderRecords.put(key, rec.ref);
5881            if (type == INTENT_SENDER_ACTIVITY_RESULT) {
5882                if (activity.pendingResults == null) {
5883                    activity.pendingResults
5884                            = new HashSet<WeakReference<PendingIntentRecord>>();
5885                }
5886                activity.pendingResults.add(rec.ref);
5887            }
5888            return rec;
5889        }
5890    }
5891
5892    public void cancelIntentSender(IIntentSender sender) {
5893        if (!(sender instanceof PendingIntentRecord)) {
5894            return;
5895        }
5896        synchronized(this) {
5897            PendingIntentRecord rec = (PendingIntentRecord)sender;
5898            try {
5899                int uid = ActivityThread.getPackageManager()
5900                        .getPackageUid(rec.key.packageName);
5901                if (uid != Binder.getCallingUid()) {
5902                    String msg = "Permission Denial: cancelIntentSender() from pid="
5903                        + Binder.getCallingPid()
5904                        + ", uid=" + Binder.getCallingUid()
5905                        + " is not allowed to cancel packges "
5906                        + rec.key.packageName;
5907                    Log.w(TAG, msg);
5908                    throw new SecurityException(msg);
5909                }
5910            } catch (RemoteException e) {
5911                throw new SecurityException(e);
5912            }
5913            cancelIntentSenderLocked(rec, true);
5914        }
5915    }
5916
5917    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5918        rec.canceled = true;
5919        mIntentSenderRecords.remove(rec.key);
5920        if (cleanActivity && rec.key.activity != null) {
5921            rec.key.activity.pendingResults.remove(rec.ref);
5922        }
5923    }
5924
5925    public String getPackageForIntentSender(IIntentSender pendingResult) {
5926        if (!(pendingResult instanceof PendingIntentRecord)) {
5927            return null;
5928        }
5929        synchronized(this) {
5930            try {
5931                PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5932                return res.key.packageName;
5933            } catch (ClassCastException e) {
5934            }
5935        }
5936        return null;
5937    }
5938
5939    public void setProcessLimit(int max) {
5940        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5941                "setProcessLimit()");
5942        mProcessLimit = max;
5943    }
5944
5945    public int getProcessLimit() {
5946        return mProcessLimit;
5947    }
5948
5949    void foregroundTokenDied(ForegroundToken token) {
5950        synchronized (ActivityManagerService.this) {
5951            synchronized (mPidsSelfLocked) {
5952                ForegroundToken cur
5953                    = mForegroundProcesses.get(token.pid);
5954                if (cur != token) {
5955                    return;
5956                }
5957                mForegroundProcesses.remove(token.pid);
5958                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
5959                if (pr == null) {
5960                    return;
5961                }
5962                pr.forcingToForeground = null;
5963                pr.foregroundServices = false;
5964            }
5965            updateOomAdjLocked();
5966        }
5967    }
5968
5969    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
5970        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5971                "setProcessForeground()");
5972        synchronized(this) {
5973            boolean changed = false;
5974
5975            synchronized (mPidsSelfLocked) {
5976                ProcessRecord pr = mPidsSelfLocked.get(pid);
5977                if (pr == null) {
5978                    Log.w(TAG, "setProcessForeground called on unknown pid: " + pid);
5979                    return;
5980                }
5981                ForegroundToken oldToken = mForegroundProcesses.get(pid);
5982                if (oldToken != null) {
5983                    oldToken.token.unlinkToDeath(oldToken, 0);
5984                    mForegroundProcesses.remove(pid);
5985                    pr.forcingToForeground = null;
5986                    changed = true;
5987                }
5988                if (isForeground && token != null) {
5989                    ForegroundToken newToken = new ForegroundToken() {
5990                        public void binderDied() {
5991                            foregroundTokenDied(this);
5992                        }
5993                    };
5994                    newToken.pid = pid;
5995                    newToken.token = token;
5996                    try {
5997                        token.linkToDeath(newToken, 0);
5998                        mForegroundProcesses.put(pid, newToken);
5999                        pr.forcingToForeground = token;
6000                        changed = true;
6001                    } catch (RemoteException e) {
6002                        // If the process died while doing this, we will later
6003                        // do the cleanup with the process death link.
6004                    }
6005                }
6006            }
6007
6008            if (changed) {
6009                updateOomAdjLocked();
6010            }
6011        }
6012    }
6013
6014    // =========================================================
6015    // PERMISSIONS
6016    // =========================================================
6017
6018    static class PermissionController extends IPermissionController.Stub {
6019        ActivityManagerService mActivityManagerService;
6020        PermissionController(ActivityManagerService activityManagerService) {
6021            mActivityManagerService = activityManagerService;
6022        }
6023
6024        public boolean checkPermission(String permission, int pid, int uid) {
6025            return mActivityManagerService.checkPermission(permission, pid,
6026                    uid) == PackageManager.PERMISSION_GRANTED;
6027        }
6028    }
6029
6030    /**
6031     * This can be called with or without the global lock held.
6032     */
6033    int checkComponentPermission(String permission, int pid, int uid,
6034            int reqUid) {
6035        // We might be performing an operation on behalf of an indirect binder
6036        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6037        // client identity accordingly before proceeding.
6038        Identity tlsIdentity = sCallerIdentity.get();
6039        if (tlsIdentity != null) {
6040            Log.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6041                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6042            uid = tlsIdentity.uid;
6043            pid = tlsIdentity.pid;
6044        }
6045
6046        // Root, system server and our own process get to do everything.
6047        if (uid == 0 || uid == Process.SYSTEM_UID || pid == MY_PID ||
6048            !Process.supportsProcesses()) {
6049            return PackageManager.PERMISSION_GRANTED;
6050        }
6051        // If the target requires a specific UID, always fail for others.
6052        if (reqUid >= 0 && uid != reqUid) {
6053            return PackageManager.PERMISSION_DENIED;
6054        }
6055        if (permission == null) {
6056            return PackageManager.PERMISSION_GRANTED;
6057        }
6058        try {
6059            return ActivityThread.getPackageManager()
6060                    .checkUidPermission(permission, uid);
6061        } catch (RemoteException e) {
6062            // Should never happen, but if it does... deny!
6063            Log.e(TAG, "PackageManager is dead?!?", e);
6064        }
6065        return PackageManager.PERMISSION_DENIED;
6066    }
6067
6068    /**
6069     * As the only public entry point for permissions checking, this method
6070     * can enforce the semantic that requesting a check on a null global
6071     * permission is automatically denied.  (Internally a null permission
6072     * string is used when calling {@link #checkComponentPermission} in cases
6073     * when only uid-based security is needed.)
6074     *
6075     * This can be called with or without the global lock held.
6076     */
6077    public int checkPermission(String permission, int pid, int uid) {
6078        if (permission == null) {
6079            return PackageManager.PERMISSION_DENIED;
6080        }
6081        return checkComponentPermission(permission, pid, uid, -1);
6082    }
6083
6084    /**
6085     * Binder IPC calls go through the public entry point.
6086     * This can be called with or without the global lock held.
6087     */
6088    int checkCallingPermission(String permission) {
6089        return checkPermission(permission,
6090                Binder.getCallingPid(),
6091                Binder.getCallingUid());
6092    }
6093
6094    /**
6095     * This can be called with or without the global lock held.
6096     */
6097    void enforceCallingPermission(String permission, String func) {
6098        if (checkCallingPermission(permission)
6099                == PackageManager.PERMISSION_GRANTED) {
6100            return;
6101        }
6102
6103        String msg = "Permission Denial: " + func + " from pid="
6104                + Binder.getCallingPid()
6105                + ", uid=" + Binder.getCallingUid()
6106                + " requires " + permission;
6107        Log.w(TAG, msg);
6108        throw new SecurityException(msg);
6109    }
6110
6111    private final boolean checkHoldingPermissionsLocked(IPackageManager pm,
6112            ProviderInfo pi, int uid, int modeFlags) {
6113        try {
6114            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6115                if ((pi.readPermission != null) &&
6116                        (pm.checkUidPermission(pi.readPermission, uid)
6117                                != PackageManager.PERMISSION_GRANTED)) {
6118                    return false;
6119                }
6120            }
6121            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6122                if ((pi.writePermission != null) &&
6123                        (pm.checkUidPermission(pi.writePermission, uid)
6124                                != PackageManager.PERMISSION_GRANTED)) {
6125                    return false;
6126                }
6127            }
6128            return true;
6129        } catch (RemoteException e) {
6130            return false;
6131        }
6132    }
6133
6134    private final boolean checkUriPermissionLocked(Uri uri, int uid,
6135            int modeFlags) {
6136        // Root gets to do everything.
6137        if (uid == 0 || !Process.supportsProcesses()) {
6138            return true;
6139        }
6140        HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6141        if (perms == null) return false;
6142        UriPermission perm = perms.get(uri);
6143        if (perm == null) return false;
6144        return (modeFlags&perm.modeFlags) == modeFlags;
6145    }
6146
6147    public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
6148        // Another redirected-binder-call permissions check as in
6149        // {@link checkComponentPermission}.
6150        Identity tlsIdentity = sCallerIdentity.get();
6151        if (tlsIdentity != null) {
6152            uid = tlsIdentity.uid;
6153            pid = tlsIdentity.pid;
6154        }
6155
6156        // Our own process gets to do everything.
6157        if (pid == MY_PID) {
6158            return PackageManager.PERMISSION_GRANTED;
6159        }
6160        synchronized(this) {
6161            return checkUriPermissionLocked(uri, uid, modeFlags)
6162                    ? PackageManager.PERMISSION_GRANTED
6163                    : PackageManager.PERMISSION_DENIED;
6164        }
6165    }
6166
6167    private void grantUriPermissionLocked(int callingUid,
6168            String targetPkg, Uri uri, int modeFlags, HistoryRecord activity) {
6169        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
6170                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6171        if (modeFlags == 0) {
6172            return;
6173        }
6174
6175        final IPackageManager pm = ActivityThread.getPackageManager();
6176
6177        // If this is not a content: uri, we can't do anything with it.
6178        if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
6179            return;
6180        }
6181
6182        String name = uri.getAuthority();
6183        ProviderInfo pi = null;
6184        ContentProviderRecord cpr
6185                = (ContentProviderRecord)mProvidersByName.get(name);
6186        if (cpr != null) {
6187            pi = cpr.info;
6188        } else {
6189            try {
6190                pi = pm.resolveContentProvider(name,
6191                        PackageManager.GET_URI_PERMISSION_PATTERNS);
6192            } catch (RemoteException ex) {
6193            }
6194        }
6195        if (pi == null) {
6196            Log.w(TAG, "No content provider found for: " + name);
6197            return;
6198        }
6199
6200        int targetUid;
6201        try {
6202            targetUid = pm.getPackageUid(targetPkg);
6203            if (targetUid < 0) {
6204                return;
6205            }
6206        } catch (RemoteException ex) {
6207            return;
6208        }
6209
6210        // First...  does the target actually need this permission?
6211        if (checkHoldingPermissionsLocked(pm, pi, targetUid, modeFlags)) {
6212            // No need to grant the target this permission.
6213            return;
6214        }
6215
6216        // Second...  maybe someone else has already granted the
6217        // permission?
6218        if (checkUriPermissionLocked(uri, targetUid, modeFlags)) {
6219            // No need to grant the target this permission.
6220            return;
6221        }
6222
6223        // Third...  is the provider allowing granting of URI permissions?
6224        if (!pi.grantUriPermissions) {
6225            throw new SecurityException("Provider " + pi.packageName
6226                    + "/" + pi.name
6227                    + " does not allow granting of Uri permissions (uri "
6228                    + uri + ")");
6229        }
6230        if (pi.uriPermissionPatterns != null) {
6231            final int N = pi.uriPermissionPatterns.length;
6232            boolean allowed = false;
6233            for (int i=0; i<N; i++) {
6234                if (pi.uriPermissionPatterns[i] != null
6235                        && pi.uriPermissionPatterns[i].match(uri.getPath())) {
6236                    allowed = true;
6237                    break;
6238                }
6239            }
6240            if (!allowed) {
6241                throw new SecurityException("Provider " + pi.packageName
6242                        + "/" + pi.name
6243                        + " does not allow granting of permission to path of Uri "
6244                        + uri);
6245            }
6246        }
6247
6248        // Fourth...  does the caller itself have permission to access
6249        // this uri?
6250        if (!checkHoldingPermissionsLocked(pm, pi, callingUid, modeFlags)) {
6251            if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6252                throw new SecurityException("Uid " + callingUid
6253                        + " does not have permission to uri " + uri);
6254            }
6255        }
6256
6257        // Okay!  So here we are: the caller has the assumed permission
6258        // to the uri, and the target doesn't.  Let's now give this to
6259        // the target.
6260
6261        HashMap<Uri, UriPermission> targetUris
6262                = mGrantedUriPermissions.get(targetUid);
6263        if (targetUris == null) {
6264            targetUris = new HashMap<Uri, UriPermission>();
6265            mGrantedUriPermissions.put(targetUid, targetUris);
6266        }
6267
6268        UriPermission perm = targetUris.get(uri);
6269        if (perm == null) {
6270            perm = new UriPermission(targetUid, uri);
6271            targetUris.put(uri, perm);
6272
6273        }
6274        perm.modeFlags |= modeFlags;
6275        if (activity == null) {
6276            perm.globalModeFlags |= modeFlags;
6277        } else if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6278            perm.readActivities.add(activity);
6279            if (activity.readUriPermissions == null) {
6280                activity.readUriPermissions = new HashSet<UriPermission>();
6281            }
6282            activity.readUriPermissions.add(perm);
6283        } else if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6284            perm.writeActivities.add(activity);
6285            if (activity.writeUriPermissions == null) {
6286                activity.writeUriPermissions = new HashSet<UriPermission>();
6287            }
6288            activity.writeUriPermissions.add(perm);
6289        }
6290    }
6291
6292    private void grantUriPermissionFromIntentLocked(int callingUid,
6293            String targetPkg, Intent intent, HistoryRecord activity) {
6294        if (intent == null) {
6295            return;
6296        }
6297        Uri data = intent.getData();
6298        if (data == null) {
6299            return;
6300        }
6301        grantUriPermissionLocked(callingUid, targetPkg, data,
6302                intent.getFlags(), activity);
6303    }
6304
6305    public void grantUriPermission(IApplicationThread caller, String targetPkg,
6306            Uri uri, int modeFlags) {
6307        synchronized(this) {
6308            final ProcessRecord r = getRecordForAppLocked(caller);
6309            if (r == null) {
6310                throw new SecurityException("Unable to find app for caller "
6311                        + caller
6312                        + " when granting permission to uri " + uri);
6313            }
6314            if (targetPkg == null) {
6315                Log.w(TAG, "grantUriPermission: null target");
6316                return;
6317            }
6318            if (uri == null) {
6319                Log.w(TAG, "grantUriPermission: null uri");
6320                return;
6321            }
6322
6323            grantUriPermissionLocked(r.info.uid, targetPkg, uri, modeFlags,
6324                    null);
6325        }
6326    }
6327
6328    private void removeUriPermissionIfNeededLocked(UriPermission perm) {
6329        if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
6330                |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
6331            HashMap<Uri, UriPermission> perms
6332                    = mGrantedUriPermissions.get(perm.uid);
6333            if (perms != null) {
6334                perms.remove(perm.uri);
6335                if (perms.size() == 0) {
6336                    mGrantedUriPermissions.remove(perm.uid);
6337                }
6338            }
6339        }
6340    }
6341
6342    private void removeActivityUriPermissionsLocked(HistoryRecord activity) {
6343        if (activity.readUriPermissions != null) {
6344            for (UriPermission perm : activity.readUriPermissions) {
6345                perm.readActivities.remove(activity);
6346                if (perm.readActivities.size() == 0 && (perm.globalModeFlags
6347                        &Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0) {
6348                    perm.modeFlags &= ~Intent.FLAG_GRANT_READ_URI_PERMISSION;
6349                    removeUriPermissionIfNeededLocked(perm);
6350                }
6351            }
6352        }
6353        if (activity.writeUriPermissions != null) {
6354            for (UriPermission perm : activity.writeUriPermissions) {
6355                perm.writeActivities.remove(activity);
6356                if (perm.writeActivities.size() == 0 && (perm.globalModeFlags
6357                        &Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0) {
6358                    perm.modeFlags &= ~Intent.FLAG_GRANT_WRITE_URI_PERMISSION;
6359                    removeUriPermissionIfNeededLocked(perm);
6360                }
6361            }
6362        }
6363    }
6364
6365    private void revokeUriPermissionLocked(int callingUid, Uri uri,
6366            int modeFlags) {
6367        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
6368                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6369        if (modeFlags == 0) {
6370            return;
6371        }
6372
6373        final IPackageManager pm = ActivityThread.getPackageManager();
6374
6375        final String authority = uri.getAuthority();
6376        ProviderInfo pi = null;
6377        ContentProviderRecord cpr
6378                = (ContentProviderRecord)mProvidersByName.get(authority);
6379        if (cpr != null) {
6380            pi = cpr.info;
6381        } else {
6382            try {
6383                pi = pm.resolveContentProvider(authority,
6384                        PackageManager.GET_URI_PERMISSION_PATTERNS);
6385            } catch (RemoteException ex) {
6386            }
6387        }
6388        if (pi == null) {
6389            Log.w(TAG, "No content provider found for: " + authority);
6390            return;
6391        }
6392
6393        // Does the caller have this permission on the URI?
6394        if (!checkHoldingPermissionsLocked(pm, pi, callingUid, modeFlags)) {
6395            // Right now, if you are not the original owner of the permission,
6396            // you are not allowed to revoke it.
6397            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6398                throw new SecurityException("Uid " + callingUid
6399                        + " does not have permission to uri " + uri);
6400            //}
6401        }
6402
6403        // Go through all of the permissions and remove any that match.
6404        final List<String> SEGMENTS = uri.getPathSegments();
6405        if (SEGMENTS != null) {
6406            final int NS = SEGMENTS.size();
6407            int N = mGrantedUriPermissions.size();
6408            for (int i=0; i<N; i++) {
6409                HashMap<Uri, UriPermission> perms
6410                        = mGrantedUriPermissions.valueAt(i);
6411                Iterator<UriPermission> it = perms.values().iterator();
6412            toploop:
6413                while (it.hasNext()) {
6414                    UriPermission perm = it.next();
6415                    Uri targetUri = perm.uri;
6416                    if (!authority.equals(targetUri.getAuthority())) {
6417                        continue;
6418                    }
6419                    List<String> targetSegments = targetUri.getPathSegments();
6420                    if (targetSegments == null) {
6421                        continue;
6422                    }
6423                    if (targetSegments.size() < NS) {
6424                        continue;
6425                    }
6426                    for (int j=0; j<NS; j++) {
6427                        if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
6428                            continue toploop;
6429                        }
6430                    }
6431                    perm.clearModes(modeFlags);
6432                    if (perm.modeFlags == 0) {
6433                        it.remove();
6434                    }
6435                }
6436                if (perms.size() == 0) {
6437                    mGrantedUriPermissions.remove(
6438                            mGrantedUriPermissions.keyAt(i));
6439                    N--;
6440                    i--;
6441                }
6442            }
6443        }
6444    }
6445
6446    public void revokeUriPermission(IApplicationThread caller, Uri uri,
6447            int modeFlags) {
6448        synchronized(this) {
6449            final ProcessRecord r = getRecordForAppLocked(caller);
6450            if (r == null) {
6451                throw new SecurityException("Unable to find app for caller "
6452                        + caller
6453                        + " when revoking permission to uri " + uri);
6454            }
6455            if (uri == null) {
6456                Log.w(TAG, "revokeUriPermission: null uri");
6457                return;
6458            }
6459
6460            modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
6461                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6462            if (modeFlags == 0) {
6463                return;
6464            }
6465
6466            final IPackageManager pm = ActivityThread.getPackageManager();
6467
6468            final String authority = uri.getAuthority();
6469            ProviderInfo pi = null;
6470            ContentProviderRecord cpr
6471                    = (ContentProviderRecord)mProvidersByName.get(authority);
6472            if (cpr != null) {
6473                pi = cpr.info;
6474            } else {
6475                try {
6476                    pi = pm.resolveContentProvider(authority,
6477                            PackageManager.GET_URI_PERMISSION_PATTERNS);
6478                } catch (RemoteException ex) {
6479                }
6480            }
6481            if (pi == null) {
6482                Log.w(TAG, "No content provider found for: " + authority);
6483                return;
6484            }
6485
6486            revokeUriPermissionLocked(r.info.uid, uri, modeFlags);
6487        }
6488    }
6489
6490    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
6491        synchronized (this) {
6492            ProcessRecord app =
6493                who != null ? getRecordForAppLocked(who) : null;
6494            if (app == null) return;
6495
6496            Message msg = Message.obtain();
6497            msg.what = WAIT_FOR_DEBUGGER_MSG;
6498            msg.obj = app;
6499            msg.arg1 = waiting ? 1 : 0;
6500            mHandler.sendMessage(msg);
6501        }
6502    }
6503
6504    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
6505        outInfo.availMem = Process.getFreeMemory();
6506        outInfo.threshold = HOME_APP_MEM;
6507        outInfo.lowMemory = outInfo.availMem <
6508                (HOME_APP_MEM + ((HIDDEN_APP_MEM-HOME_APP_MEM)/2));
6509    }
6510
6511    // =========================================================
6512    // TASK MANAGEMENT
6513    // =========================================================
6514
6515    public List getTasks(int maxNum, int flags,
6516                         IThumbnailReceiver receiver) {
6517        ArrayList list = new ArrayList();
6518
6519        PendingThumbnailsRecord pending = null;
6520        IApplicationThread topThumbnail = null;
6521        HistoryRecord topRecord = null;
6522
6523        synchronized(this) {
6524            if (localLOGV) Log.v(
6525                TAG, "getTasks: max=" + maxNum + ", flags=" + flags
6526                + ", receiver=" + receiver);
6527
6528            if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
6529                    != PackageManager.PERMISSION_GRANTED) {
6530                if (receiver != null) {
6531                    // If the caller wants to wait for pending thumbnails,
6532                    // it ain't gonna get them.
6533                    try {
6534                        receiver.finished();
6535                    } catch (RemoteException ex) {
6536                    }
6537                }
6538                String msg = "Permission Denial: getTasks() from pid="
6539                        + Binder.getCallingPid()
6540                        + ", uid=" + Binder.getCallingUid()
6541                        + " requires " + android.Manifest.permission.GET_TASKS;
6542                Log.w(TAG, msg);
6543                throw new SecurityException(msg);
6544            }
6545
6546            int pos = mHistory.size()-1;
6547            HistoryRecord next =
6548                pos >= 0 ? (HistoryRecord)mHistory.get(pos) : null;
6549            HistoryRecord top = null;
6550            CharSequence topDescription = null;
6551            TaskRecord curTask = null;
6552            int numActivities = 0;
6553            int numRunning = 0;
6554            while (pos >= 0 && maxNum > 0) {
6555                final HistoryRecord r = next;
6556                pos--;
6557                next = pos >= 0 ? (HistoryRecord)mHistory.get(pos) : null;
6558
6559                // Initialize state for next task if needed.
6560                if (top == null ||
6561                        (top.state == ActivityState.INITIALIZING
6562                            && top.task == r.task)) {
6563                    top = r;
6564                    topDescription = r.description;
6565                    curTask = r.task;
6566                    numActivities = numRunning = 0;
6567                }
6568
6569                // Add 'r' into the current task.
6570                numActivities++;
6571                if (r.app != null && r.app.thread != null) {
6572                    numRunning++;
6573                }
6574                if (topDescription == null) {
6575                    topDescription = r.description;
6576                }
6577
6578                if (localLOGV) Log.v(
6579                    TAG, r.intent.getComponent().flattenToShortString()
6580                    + ": task=" + r.task);
6581
6582                // If the next one is a different task, generate a new
6583                // TaskInfo entry for what we have.
6584                if (next == null || next.task != curTask) {
6585                    ActivityManager.RunningTaskInfo ci
6586                            = new ActivityManager.RunningTaskInfo();
6587                    ci.id = curTask.taskId;
6588                    ci.baseActivity = r.intent.getComponent();
6589                    ci.topActivity = top.intent.getComponent();
6590                    ci.thumbnail = top.thumbnail;
6591                    ci.description = topDescription;
6592                    ci.numActivities = numActivities;
6593                    ci.numRunning = numRunning;
6594                    //System.out.println(
6595                    //    "#" + maxNum + ": " + " descr=" + ci.description);
6596                    if (ci.thumbnail == null && receiver != null) {
6597                        if (localLOGV) Log.v(
6598                            TAG, "State=" + top.state + "Idle=" + top.idle
6599                            + " app=" + top.app
6600                            + " thr=" + (top.app != null ? top.app.thread : null));
6601                        if (top.state == ActivityState.RESUMED
6602                                || top.state == ActivityState.PAUSING) {
6603                            if (top.idle && top.app != null
6604                                && top.app.thread != null) {
6605                                topRecord = top;
6606                                topThumbnail = top.app.thread;
6607                            } else {
6608                                top.thumbnailNeeded = true;
6609                            }
6610                        }
6611                        if (pending == null) {
6612                            pending = new PendingThumbnailsRecord(receiver);
6613                        }
6614                        pending.pendingRecords.add(top);
6615                    }
6616                    list.add(ci);
6617                    maxNum--;
6618                    top = null;
6619                }
6620            }
6621
6622            if (pending != null) {
6623                mPendingThumbnails.add(pending);
6624            }
6625        }
6626
6627        if (localLOGV) Log.v(TAG, "We have pending thumbnails: " + pending);
6628
6629        if (topThumbnail != null) {
6630            if (localLOGV) Log.v(TAG, "Requesting top thumbnail");
6631            try {
6632                topThumbnail.requestThumbnail(topRecord);
6633            } catch (Exception e) {
6634                Log.w(TAG, "Exception thrown when requesting thumbnail", e);
6635                sendPendingThumbnail(null, topRecord, null, null, true);
6636            }
6637        }
6638
6639        if (pending == null && receiver != null) {
6640            // In this case all thumbnails were available and the client
6641            // is being asked to be told when the remaining ones come in...
6642            // which is unusually, since the top-most currently running
6643            // activity should never have a canned thumbnail!  Oh well.
6644            try {
6645                receiver.finished();
6646            } catch (RemoteException ex) {
6647            }
6648        }
6649
6650        return list;
6651    }
6652
6653    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
6654            int flags) {
6655        synchronized (this) {
6656            enforceCallingPermission(android.Manifest.permission.GET_TASKS,
6657                    "getRecentTasks()");
6658
6659            final int N = mRecentTasks.size();
6660            ArrayList<ActivityManager.RecentTaskInfo> res
6661                    = new ArrayList<ActivityManager.RecentTaskInfo>(
6662                            maxNum < N ? maxNum : N);
6663            for (int i=0; i<N && maxNum > 0; i++) {
6664                TaskRecord tr = mRecentTasks.get(i);
6665                if (((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
6666                        || (tr.intent == null)
6667                        || ((tr.intent.getFlags()
6668                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
6669                    ActivityManager.RecentTaskInfo rti
6670                            = new ActivityManager.RecentTaskInfo();
6671                    rti.id = tr.numActivities > 0 ? tr.taskId : -1;
6672                    rti.baseIntent = new Intent(
6673                            tr.intent != null ? tr.intent : tr.affinityIntent);
6674                    rti.origActivity = tr.origActivity;
6675                    res.add(rti);
6676                    maxNum--;
6677                }
6678            }
6679            return res;
6680        }
6681    }
6682
6683    private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
6684        int j;
6685        TaskRecord startTask = ((HistoryRecord)mHistory.get(startIndex)).task;
6686        TaskRecord jt = startTask;
6687
6688        // First look backwards
6689        for (j=startIndex-1; j>=0; j--) {
6690            HistoryRecord r = (HistoryRecord)mHistory.get(j);
6691            if (r.task != jt) {
6692                jt = r.task;
6693                if (affinity.equals(jt.affinity)) {
6694                    return j;
6695                }
6696            }
6697        }
6698
6699        // Now look forwards
6700        final int N = mHistory.size();
6701        jt = startTask;
6702        for (j=startIndex+1; j<N; j++) {
6703            HistoryRecord r = (HistoryRecord)mHistory.get(j);
6704            if (r.task != jt) {
6705                if (affinity.equals(jt.affinity)) {
6706                    return j;
6707                }
6708                jt = r.task;
6709            }
6710        }
6711
6712        // Might it be at the top?
6713        if (affinity.equals(((HistoryRecord)mHistory.get(N-1)).task.affinity)) {
6714            return N-1;
6715        }
6716
6717        return -1;
6718    }
6719
6720    /**
6721     * Perform a reset of the given task, if needed as part of launching it.
6722     * Returns the new HistoryRecord at the top of the task.
6723     */
6724    private final HistoryRecord resetTaskIfNeededLocked(HistoryRecord taskTop,
6725            HistoryRecord newActivity) {
6726        boolean forceReset = (newActivity.info.flags
6727                &ActivityInfo.FLAG_CLEAR_TASK_ON_LAUNCH) != 0;
6728        if (taskTop.task.getInactiveDuration() > ACTIVITY_INACTIVE_RESET_TIME) {
6729            if ((newActivity.info.flags
6730                    &ActivityInfo.FLAG_ALWAYS_RETAIN_TASK_STATE) == 0) {
6731                forceReset = true;
6732            }
6733        }
6734
6735        final TaskRecord task = taskTop.task;
6736
6737        // We are going to move through the history list so that we can look
6738        // at each activity 'target' with 'below' either the interesting
6739        // activity immediately below it in the stack or null.
6740        HistoryRecord target = null;
6741        int targetI = 0;
6742        int taskTopI = -1;
6743        int replyChainEnd = -1;
6744        int lastReparentPos = -1;
6745        for (int i=mHistory.size()-1; i>=-1; i--) {
6746            HistoryRecord below = i >= 0 ? (HistoryRecord)mHistory.get(i) : null;
6747
6748            if (below != null && below.finishing) {
6749                continue;
6750            }
6751            if (target == null) {
6752                target = below;
6753                targetI = i;
6754                // If we were in the middle of a reply chain before this
6755                // task, it doesn't appear like the root of the chain wants
6756                // anything interesting, so drop it.
6757                replyChainEnd = -1;
6758                continue;
6759            }
6760
6761            final int flags = target.info.flags;
6762
6763            final boolean finishOnTaskLaunch =
6764                (flags&ActivityInfo.FLAG_FINISH_ON_TASK_LAUNCH) != 0;
6765            final boolean allowTaskReparenting =
6766                (flags&ActivityInfo.FLAG_ALLOW_TASK_REPARENTING) != 0;
6767
6768            if (target.task == task) {
6769                // We are inside of the task being reset...  we'll either
6770                // finish this activity, push it out for another task,
6771                // or leave it as-is.  We only do this
6772                // for activities that are not the root of the task (since
6773                // if we finish the root, we may no longer have the task!).
6774                if (taskTopI < 0) {
6775                    taskTopI = targetI;
6776                }
6777                if (below != null && below.task == task) {
6778                    final boolean clearWhenTaskReset =
6779                            (target.intent.getFlags()
6780                                    &Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0;
6781                    if (!finishOnTaskLaunch && !clearWhenTaskReset && target.resultTo != null) {
6782                        // If this activity is sending a reply to a previous
6783                        // activity, we can't do anything with it now until
6784                        // we reach the start of the reply chain.
6785                        // XXX note that we are assuming the result is always
6786                        // to the previous activity, which is almost always
6787                        // the case but we really shouldn't count on.
6788                        if (replyChainEnd < 0) {
6789                            replyChainEnd = targetI;
6790                        }
6791                    } else if (!finishOnTaskLaunch && !clearWhenTaskReset && allowTaskReparenting
6792                            && target.taskAffinity != null
6793                            && !target.taskAffinity.equals(task.affinity)) {
6794                        // If this activity has an affinity for another
6795                        // task, then we need to move it out of here.  We will
6796                        // move it as far out of the way as possible, to the
6797                        // bottom of the activity stack.  This also keeps it
6798                        // correctly ordered with any activities we previously
6799                        // moved.
6800                        HistoryRecord p = (HistoryRecord)mHistory.get(0);
6801                        if (target.taskAffinity != null
6802                                && target.taskAffinity.equals(p.task.affinity)) {
6803                            // If the activity currently at the bottom has the
6804                            // same task affinity as the one we are moving,
6805                            // then merge it into the same task.
6806                            target.task = p.task;
6807                            if (DEBUG_TASKS) Log.v(TAG, "Start pushing activity " + target
6808                                    + " out to bottom task " + p.task);
6809                        } else {
6810                            mCurTask++;
6811                            if (mCurTask <= 0) {
6812                                mCurTask = 1;
6813                            }
6814                            target.task = new TaskRecord(mCurTask, target.info, null,
6815                                    (target.info.flags&ActivityInfo.FLAG_CLEAR_TASK_ON_LAUNCH) != 0);
6816                            target.task.affinityIntent = target.intent;
6817                            if (DEBUG_TASKS) Log.v(TAG, "Start pushing activity " + target
6818                                    + " out to new task " + target.task);
6819                        }
6820                        mWindowManager.setAppGroupId(target, task.taskId);
6821                        if (replyChainEnd < 0) {
6822                            replyChainEnd = targetI;
6823                        }
6824                        int dstPos = 0;
6825                        for (int srcPos=targetI; srcPos<=replyChainEnd; srcPos++) {
6826                            p = (HistoryRecord)mHistory.get(srcPos);
6827                            if (p.finishing) {
6828                                continue;
6829                            }
6830                            if (DEBUG_TASKS) Log.v(TAG, "Pushing next activity " + p
6831                                    + " out to target's task " + target.task);
6832                            task.numActivities--;
6833                            p.task = target.task;
6834                            target.task.numActivities++;
6835                            mHistory.remove(srcPos);
6836                            mHistory.add(dstPos, p);
6837                            mWindowManager.moveAppToken(dstPos, p);
6838                            mWindowManager.setAppGroupId(p, p.task.taskId);
6839                            dstPos++;
6840                            if (VALIDATE_TOKENS) {
6841                                mWindowManager.validateAppTokens(mHistory);
6842                            }
6843                            i++;
6844                        }
6845                        if (taskTop == p) {
6846                            taskTop = below;
6847                        }
6848                        if (taskTopI == replyChainEnd) {
6849                            taskTopI = -1;
6850                        }
6851                        replyChainEnd = -1;
6852                        addRecentTask(target.task);
6853                    } else if (forceReset || finishOnTaskLaunch
6854                            || clearWhenTaskReset) {
6855                        // If the activity should just be removed -- either
6856                        // because it asks for it, or the task should be
6857                        // cleared -- then finish it and anything that is
6858                        // part of its reply chain.
6859                        if (clearWhenTaskReset) {
6860                            // In this case, we want to finish this activity
6861                            // and everything above it, so be sneaky and pretend
6862                            // like these are all in the reply chain.
6863                            replyChainEnd = targetI+1;
6864                            while (replyChainEnd < mHistory.size() &&
6865                                    ((HistoryRecord)mHistory.get(
6866                                                replyChainEnd)).task == task) {
6867                                replyChainEnd++;
6868                            }
6869                            replyChainEnd--;
6870                        } else if (replyChainEnd < 0) {
6871                            replyChainEnd = targetI;
6872                        }
6873                        HistoryRecord p = null;
6874                        for (int srcPos=targetI; srcPos<=replyChainEnd; srcPos++) {
6875                            p = (HistoryRecord)mHistory.get(srcPos);
6876                            if (p.finishing) {
6877                                continue;
6878                            }
6879                            if (finishActivityLocked(p, srcPos,
6880                                    Activity.RESULT_CANCELED, null, "reset")) {
6881                                replyChainEnd--;
6882                                srcPos--;
6883                            }
6884                        }
6885                        if (taskTop == p) {
6886                            taskTop = below;
6887                        }
6888                        if (taskTopI == replyChainEnd) {
6889                            taskTopI = -1;
6890                        }
6891                        replyChainEnd = -1;
6892                    } else {
6893                        // If we were in the middle of a chain, well the
6894                        // activity that started it all doesn't want anything
6895                        // special, so leave it all as-is.
6896                        replyChainEnd = -1;
6897                    }
6898                } else {
6899                    // Reached the bottom of the task -- any reply chain
6900                    // should be left as-is.
6901                    replyChainEnd = -1;
6902                }
6903
6904            } else if (target.resultTo != null) {
6905                // If this activity is sending a reply to a previous
6906                // activity, we can't do anything with it now until
6907                // we reach the start of the reply chain.
6908                // XXX note that we are assuming the result is always
6909                // to the previous activity, which is almost always
6910                // the case but we really shouldn't count on.
6911                if (replyChainEnd < 0) {
6912                    replyChainEnd = targetI;
6913                }
6914
6915            } else if (taskTopI >= 0 && allowTaskReparenting
6916                    && task.affinity != null
6917                    && task.affinity.equals(target.taskAffinity)) {
6918                // We are inside of another task...  if this activity has
6919                // an affinity for our task, then either remove it if we are
6920                // clearing or move it over to our task.  Note that
6921                // we currently punt on the case where we are resetting a
6922                // task that is not at the top but who has activities above
6923                // with an affinity to it...  this is really not a normal
6924                // case, and we will need to later pull that task to the front
6925                // and usually at that point we will do the reset and pick
6926                // up those remaining activities.  (This only happens if
6927                // someone starts an activity in a new task from an activity
6928                // in a task that is not currently on top.)
6929                if (forceReset || finishOnTaskLaunch) {
6930                    if (replyChainEnd < 0) {
6931                        replyChainEnd = targetI;
6932                    }
6933                    HistoryRecord p = null;
6934                    for (int srcPos=targetI; srcPos<=replyChainEnd; srcPos++) {
6935                        p = (HistoryRecord)mHistory.get(srcPos);
6936                        if (p.finishing) {
6937                            continue;
6938                        }
6939                        if (finishActivityLocked(p, srcPos,
6940                                Activity.RESULT_CANCELED, null, "reset")) {
6941                            taskTopI--;
6942                            lastReparentPos--;
6943                            replyChainEnd--;
6944                            srcPos--;
6945                        }
6946                    }
6947                    replyChainEnd = -1;
6948                } else {
6949                    if (replyChainEnd < 0) {
6950                        replyChainEnd = targetI;
6951                    }
6952                    for (int srcPos=replyChainEnd; srcPos>=targetI; srcPos--) {
6953                        HistoryRecord p = (HistoryRecord)mHistory.get(srcPos);
6954                        if (p.finishing) {
6955                            continue;
6956                        }
6957                        if (lastReparentPos < 0) {
6958                            lastReparentPos = taskTopI;
6959                            taskTop = p;
6960                        } else {
6961                            lastReparentPos--;
6962                        }
6963                        mHistory.remove(srcPos);
6964                        p.task.numActivities--;
6965                        p.task = task;
6966                        mHistory.add(lastReparentPos, p);
6967                        if (DEBUG_TASKS) Log.v(TAG, "Pulling activity " + p
6968                                + " in to resetting task " + task);
6969                        task.numActivities++;
6970                        mWindowManager.moveAppToken(lastReparentPos, p);
6971                        mWindowManager.setAppGroupId(p, p.task.taskId);
6972                        if (VALIDATE_TOKENS) {
6973                            mWindowManager.validateAppTokens(mHistory);
6974                        }
6975                    }
6976                    replyChainEnd = -1;
6977
6978                    // Now we've moved it in to place...  but what if this is
6979                    // a singleTop activity and we have put it on top of another
6980                    // instance of the same activity?  Then we drop the instance
6981                    // below so it remains singleTop.
6982                    if (target.info.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP) {
6983                        for (int j=lastReparentPos-1; j>=0; j--) {
6984                            HistoryRecord p = (HistoryRecord)mHistory.get(j);
6985                            if (p.finishing) {
6986                                continue;
6987                            }
6988                            if (p.intent.getComponent().equals(target.intent.getComponent())) {
6989                                if (finishActivityLocked(p, j,
6990                                        Activity.RESULT_CANCELED, null, "replace")) {
6991                                    taskTopI--;
6992                                    lastReparentPos--;
6993                                }
6994                            }
6995                        }
6996                    }
6997                }
6998            }
6999
7000            target = below;
7001            targetI = i;
7002        }
7003
7004        return taskTop;
7005    }
7006
7007    /**
7008     * TODO: Add mController hook
7009     */
7010    public void moveTaskToFront(int task) {
7011        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7012                "moveTaskToFront()");
7013
7014        synchronized(this) {
7015            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7016                    Binder.getCallingUid(), "Task to front")) {
7017                return;
7018            }
7019            final long origId = Binder.clearCallingIdentity();
7020            try {
7021                int N = mRecentTasks.size();
7022                for (int i=0; i<N; i++) {
7023                    TaskRecord tr = mRecentTasks.get(i);
7024                    if (tr.taskId == task) {
7025                        moveTaskToFrontLocked(tr, null);
7026                        return;
7027                    }
7028                }
7029                for (int i=mHistory.size()-1; i>=0; i--) {
7030                    HistoryRecord hr = (HistoryRecord)mHistory.get(i);
7031                    if (hr.task.taskId == task) {
7032                        moveTaskToFrontLocked(hr.task, null);
7033                        return;
7034                    }
7035                }
7036            } finally {
7037                Binder.restoreCallingIdentity(origId);
7038            }
7039        }
7040    }
7041
7042    private final void moveTaskToFrontLocked(TaskRecord tr, HistoryRecord reason) {
7043        if (DEBUG_SWITCH) Log.v(TAG, "moveTaskToFront: " + tr);
7044
7045        final int task = tr.taskId;
7046        int top = mHistory.size()-1;
7047
7048        if (top < 0 || ((HistoryRecord)mHistory.get(top)).task.taskId == task) {
7049            // nothing to do!
7050            return;
7051        }
7052
7053        ArrayList moved = new ArrayList();
7054
7055        // Applying the affinities may have removed entries from the history,
7056        // so get the size again.
7057        top = mHistory.size()-1;
7058        int pos = top;
7059
7060        // Shift all activities with this task up to the top
7061        // of the stack, keeping them in the same internal order.
7062        while (pos >= 0) {
7063            HistoryRecord r = (HistoryRecord)mHistory.get(pos);
7064            if (localLOGV) Log.v(
7065                TAG, "At " + pos + " ckp " + r.task + ": " + r);
7066            boolean first = true;
7067            if (r.task.taskId == task) {
7068                if (localLOGV) Log.v(TAG, "Removing and adding at " + top);
7069                mHistory.remove(pos);
7070                mHistory.add(top, r);
7071                moved.add(0, r);
7072                top--;
7073                if (first) {
7074                    addRecentTask(r.task);
7075                    first = false;
7076                }
7077            }
7078            pos--;
7079        }
7080
7081        if (DEBUG_TRANSITION) Log.v(TAG,
7082                "Prepare to front transition: task=" + tr);
7083        if (reason != null &&
7084                (reason.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) {
7085            mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_NONE);
7086            HistoryRecord r = topRunningActivityLocked(null);
7087            if (r != null) {
7088                mNoAnimActivities.add(r);
7089            }
7090        } else {
7091            mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_TASK_TO_FRONT);
7092        }
7093
7094        mWindowManager.moveAppTokensToTop(moved);
7095        if (VALIDATE_TOKENS) {
7096            mWindowManager.validateAppTokens(mHistory);
7097        }
7098
7099        finishTaskMove(task);
7100        EventLog.writeEvent(LOG_TASK_TO_FRONT, task);
7101    }
7102
7103    private final void finishTaskMove(int task) {
7104        resumeTopActivityLocked(null);
7105    }
7106
7107    public void moveTaskToBack(int task) {
7108        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7109                "moveTaskToBack()");
7110
7111        synchronized(this) {
7112            if (mResumedActivity != null && mResumedActivity.task.taskId == task) {
7113                if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7114                        Binder.getCallingUid(), "Task to back")) {
7115                    return;
7116                }
7117            }
7118            final long origId = Binder.clearCallingIdentity();
7119            moveTaskToBackLocked(task, null);
7120            Binder.restoreCallingIdentity(origId);
7121        }
7122    }
7123
7124    /**
7125     * Moves an activity, and all of the other activities within the same task, to the bottom
7126     * of the history stack.  The activity's order within the task is unchanged.
7127     *
7128     * @param token A reference to the activity we wish to move
7129     * @param nonRoot If false then this only works if the activity is the root
7130     *                of a task; if true it will work for any activity in a task.
7131     * @return Returns true if the move completed, false if not.
7132     */
7133    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7134        synchronized(this) {
7135            final long origId = Binder.clearCallingIdentity();
7136            int taskId = getTaskForActivityLocked(token, !nonRoot);
7137            if (taskId >= 0) {
7138                return moveTaskToBackLocked(taskId, null);
7139            }
7140            Binder.restoreCallingIdentity(origId);
7141        }
7142        return false;
7143    }
7144
7145    /**
7146     * Worker method for rearranging history stack.  Implements the function of moving all
7147     * activities for a specific task (gathering them if disjoint) into a single group at the
7148     * bottom of the stack.
7149     *
7150     * If a watcher is installed, the action is preflighted and the watcher has an opportunity
7151     * to premeptively cancel the move.
7152     *
7153     * @param task The taskId to collect and move to the bottom.
7154     * @return Returns true if the move completed, false if not.
7155     */
7156    private final boolean moveTaskToBackLocked(int task, HistoryRecord reason) {
7157        Log.i(TAG, "moveTaskToBack: " + task);
7158
7159        // If we have a watcher, preflight the move before committing to it.  First check
7160        // for *other* available tasks, but if none are available, then try again allowing the
7161        // current task to be selected.
7162        if (mController != null) {
7163            HistoryRecord next = topRunningActivityLocked(null, task);
7164            if (next == null) {
7165                next = topRunningActivityLocked(null, 0);
7166            }
7167            if (next != null) {
7168                // ask watcher if this is allowed
7169                boolean moveOK = true;
7170                try {
7171                    moveOK = mController.activityResuming(next.packageName);
7172                } catch (RemoteException e) {
7173                    mController = null;
7174                }
7175                if (!moveOK) {
7176                    return false;
7177                }
7178            }
7179        }
7180
7181        ArrayList moved = new ArrayList();
7182
7183        if (DEBUG_TRANSITION) Log.v(TAG,
7184                "Prepare to back transition: task=" + task);
7185
7186        final int N = mHistory.size();
7187        int bottom = 0;
7188        int pos = 0;
7189
7190        // Shift all activities with this task down to the bottom
7191        // of the stack, keeping them in the same internal order.
7192        while (pos < N) {
7193            HistoryRecord r = (HistoryRecord)mHistory.get(pos);
7194            if (localLOGV) Log.v(
7195                TAG, "At " + pos + " ckp " + r.task + ": " + r);
7196            if (r.task.taskId == task) {
7197                if (localLOGV) Log.v(TAG, "Removing and adding at " + (N-1));
7198                mHistory.remove(pos);
7199                mHistory.add(bottom, r);
7200                moved.add(r);
7201                bottom++;
7202            }
7203            pos++;
7204        }
7205
7206        if (reason != null &&
7207                (reason.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) {
7208            mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_NONE);
7209            HistoryRecord r = topRunningActivityLocked(null);
7210            if (r != null) {
7211                mNoAnimActivities.add(r);
7212            }
7213        } else {
7214            mWindowManager.prepareAppTransition(WindowManagerPolicy.TRANSIT_TASK_TO_BACK);
7215        }
7216        mWindowManager.moveAppTokensToBottom(moved);
7217        if (VALIDATE_TOKENS) {
7218            mWindowManager.validateAppTokens(mHistory);
7219        }
7220
7221        finishTaskMove(task);
7222        return true;
7223    }
7224
7225    public void moveTaskBackwards(int task) {
7226        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7227                "moveTaskBackwards()");
7228
7229        synchronized(this) {
7230            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7231                    Binder.getCallingUid(), "Task backwards")) {
7232                return;
7233            }
7234            final long origId = Binder.clearCallingIdentity();
7235            moveTaskBackwardsLocked(task);
7236            Binder.restoreCallingIdentity(origId);
7237        }
7238    }
7239
7240    private final void moveTaskBackwardsLocked(int task) {
7241        Log.e(TAG, "moveTaskBackwards not yet implemented!");
7242    }
7243
7244    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7245        synchronized(this) {
7246            return getTaskForActivityLocked(token, onlyRoot);
7247        }
7248    }
7249
7250    int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
7251        final int N = mHistory.size();
7252        TaskRecord lastTask = null;
7253        for (int i=0; i<N; i++) {
7254            HistoryRecord r = (HistoryRecord)mHistory.get(i);
7255            if (r == token) {
7256                if (!onlyRoot || lastTask != r.task) {
7257                    return r.task.taskId;
7258                }
7259                return -1;
7260            }
7261            lastTask = r.task;
7262        }
7263
7264        return -1;
7265    }
7266
7267    /**
7268     * Returns the top activity in any existing task matching the given
7269     * Intent.  Returns null if no such task is found.
7270     */
7271    private HistoryRecord findTaskLocked(Intent intent, ActivityInfo info) {
7272        ComponentName cls = intent.getComponent();
7273        if (info.targetActivity != null) {
7274            cls = new ComponentName(info.packageName, info.targetActivity);
7275        }
7276
7277        TaskRecord cp = null;
7278
7279        final int N = mHistory.size();
7280        for (int i=(N-1); i>=0; i--) {
7281            HistoryRecord r = (HistoryRecord)mHistory.get(i);
7282            if (!r.finishing && r.task != cp
7283                    && r.launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
7284                cp = r.task;
7285                //Log.i(TAG, "Comparing existing cls=" + r.task.intent.getComponent().flattenToShortString()
7286                //        + "/aff=" + r.task.affinity + " to new cls="
7287                //        + intent.getComponent().flattenToShortString() + "/aff=" + taskAffinity);
7288                if (r.task.affinity != null) {
7289                    if (r.task.affinity.equals(info.taskAffinity)) {
7290                        //Log.i(TAG, "Found matching affinity!");
7291                        return r;
7292                    }
7293                } else if (r.task.intent != null
7294                        && r.task.intent.getComponent().equals(cls)) {
7295                    //Log.i(TAG, "Found matching class!");
7296                    //dump();
7297                    //Log.i(TAG, "For Intent " + intent + " bringing to top: " + r.intent);
7298                    return r;
7299                } else if (r.task.affinityIntent != null
7300                        && r.task.affinityIntent.getComponent().equals(cls)) {
7301                    //Log.i(TAG, "Found matching class!");
7302                    //dump();
7303                    //Log.i(TAG, "For Intent " + intent + " bringing to top: " + r.intent);
7304                    return r;
7305                }
7306            }
7307        }
7308
7309        return null;
7310    }
7311
7312    /**
7313     * Returns the first activity (starting from the top of the stack) that
7314     * is the same as the given activity.  Returns null if no such activity
7315     * is found.
7316     */
7317    private HistoryRecord findActivityLocked(Intent intent, ActivityInfo info) {
7318        ComponentName cls = intent.getComponent();
7319        if (info.targetActivity != null) {
7320            cls = new ComponentName(info.packageName, info.targetActivity);
7321        }
7322
7323        final int N = mHistory.size();
7324        for (int i=(N-1); i>=0; i--) {
7325            HistoryRecord r = (HistoryRecord)mHistory.get(i);
7326            if (!r.finishing) {
7327                if (r.intent.getComponent().equals(cls)) {
7328                    //Log.i(TAG, "Found matching class!");
7329                    //dump();
7330                    //Log.i(TAG, "For Intent " + intent + " bringing to top: " + r.intent);
7331                    return r;
7332                }
7333            }
7334        }
7335
7336        return null;
7337    }
7338
7339    public void finishOtherInstances(IBinder token, ComponentName className) {
7340        synchronized(this) {
7341            final long origId = Binder.clearCallingIdentity();
7342
7343            int N = mHistory.size();
7344            TaskRecord lastTask = null;
7345            for (int i=0; i<N; i++) {
7346                HistoryRecord r = (HistoryRecord)mHistory.get(i);
7347                if (r.realActivity.equals(className)
7348                        && r != token && lastTask != r.task) {
7349                    if (finishActivityLocked(r, i, Activity.RESULT_CANCELED,
7350                            null, "others")) {
7351                        i--;
7352                        N--;
7353                    }
7354                }
7355                lastTask = r.task;
7356            }
7357
7358            Binder.restoreCallingIdentity(origId);
7359        }
7360    }
7361
7362    // =========================================================
7363    // THUMBNAILS
7364    // =========================================================
7365
7366    public void reportThumbnail(IBinder token,
7367            Bitmap thumbnail, CharSequence description) {
7368        //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
7369        final long origId = Binder.clearCallingIdentity();
7370        sendPendingThumbnail(null, token, thumbnail, description, true);
7371        Binder.restoreCallingIdentity(origId);
7372    }
7373
7374    final void sendPendingThumbnail(HistoryRecord r, IBinder token,
7375            Bitmap thumbnail, CharSequence description, boolean always) {
7376        TaskRecord task = null;
7377        ArrayList receivers = null;
7378
7379        //System.out.println("Send pending thumbnail: " + r);
7380
7381        synchronized(this) {
7382            if (r == null) {
7383                int index = indexOfTokenLocked(token);
7384                if (index < 0) {
7385                    return;
7386                }
7387                r = (HistoryRecord)mHistory.get(index);
7388            }
7389            if (thumbnail == null) {
7390                thumbnail = r.thumbnail;
7391                description = r.description;
7392            }
7393            if (thumbnail == null && !always) {
7394                // If there is no thumbnail, and this entry is not actually
7395                // going away, then abort for now and pick up the next
7396                // thumbnail we get.
7397                return;
7398            }
7399            task = r.task;
7400
7401            int N = mPendingThumbnails.size();
7402            int i=0;
7403            while (i<N) {
7404                PendingThumbnailsRecord pr =
7405                    (PendingThumbnailsRecord)mPendingThumbnails.get(i);
7406                //System.out.println("Looking in " + pr.pendingRecords);
7407                if (pr.pendingRecords.remove(r)) {
7408                    if (receivers == null) {
7409                        receivers = new ArrayList();
7410                    }
7411                    receivers.add(pr);
7412                    if (pr.pendingRecords.size() == 0) {
7413                        pr.finished = true;
7414                        mPendingThumbnails.remove(i);
7415                        N--;
7416                        continue;
7417                    }
7418                }
7419                i++;
7420            }
7421        }
7422
7423        if (receivers != null) {
7424            final int N = receivers.size();
7425            for (int i=0; i<N; i++) {
7426                try {
7427                    PendingThumbnailsRecord pr =
7428                        (PendingThumbnailsRecord)receivers.get(i);
7429                    pr.receiver.newThumbnail(
7430                        task != null ? task.taskId : -1, thumbnail, description);
7431                    if (pr.finished) {
7432                        pr.receiver.finished();
7433                    }
7434                } catch (Exception e) {
7435                    Log.w(TAG, "Exception thrown when sending thumbnail", e);
7436                }
7437            }
7438        }
7439    }
7440
7441    // =========================================================
7442    // CONTENT PROVIDERS
7443    // =========================================================
7444
7445    private final List generateApplicationProvidersLocked(ProcessRecord app) {
7446        List providers = null;
7447        try {
7448            providers = ActivityThread.getPackageManager().
7449                queryContentProviders(app.processName, app.info.uid,
7450                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
7451        } catch (RemoteException ex) {
7452        }
7453        if (providers != null) {
7454            final int N = providers.size();
7455            for (int i=0; i<N; i++) {
7456                ProviderInfo cpi =
7457                    (ProviderInfo)providers.get(i);
7458                ContentProviderRecord cpr =
7459                    (ContentProviderRecord)mProvidersByClass.get(cpi.name);
7460                if (cpr == null) {
7461                    cpr = new ContentProviderRecord(cpi, app.info);
7462                    mProvidersByClass.put(cpi.name, cpr);
7463                }
7464                app.pubProviders.put(cpi.name, cpr);
7465                app.addPackage(cpi.applicationInfo.packageName);
7466                ensurePackageDexOpt(cpi.applicationInfo.packageName);
7467            }
7468        }
7469        return providers;
7470    }
7471
7472    private final String checkContentProviderPermissionLocked(
7473            ProviderInfo cpi, ProcessRecord r, int mode) {
7474        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
7475        final int callingUid = (r != null) ? r.info.uid : Binder.getCallingUid();
7476        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
7477                cpi.exported ? -1 : cpi.applicationInfo.uid)
7478                == PackageManager.PERMISSION_GRANTED
7479                && mode == ParcelFileDescriptor.MODE_READ_ONLY || mode == -1) {
7480            return null;
7481        }
7482        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
7483                cpi.exported ? -1 : cpi.applicationInfo.uid)
7484                == PackageManager.PERMISSION_GRANTED) {
7485            return null;
7486        }
7487
7488        PathPermission[] pps = cpi.pathPermissions;
7489        if (pps != null) {
7490            int i = pps.length;
7491            while (i > 0) {
7492                i--;
7493                PathPermission pp = pps[i];
7494                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
7495                        cpi.exported ? -1 : cpi.applicationInfo.uid)
7496                        == PackageManager.PERMISSION_GRANTED
7497                        && mode == ParcelFileDescriptor.MODE_READ_ONLY || mode == -1) {
7498                    return null;
7499                }
7500                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
7501                        cpi.exported ? -1 : cpi.applicationInfo.uid)
7502                        == PackageManager.PERMISSION_GRANTED) {
7503                    return null;
7504                }
7505            }
7506        }
7507
7508        String msg = "Permission Denial: opening provider " + cpi.name
7509                + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7510                + ", uid=" + callingUid + ") requires "
7511                + cpi.readPermission + " or " + cpi.writePermission;
7512        Log.w(TAG, msg);
7513        return msg;
7514    }
7515
7516    private final ContentProviderHolder getContentProviderImpl(
7517        IApplicationThread caller, String name) {
7518        ContentProviderRecord cpr;
7519        ProviderInfo cpi = null;
7520
7521        synchronized(this) {
7522            ProcessRecord r = null;
7523            if (caller != null) {
7524                r = getRecordForAppLocked(caller);
7525                if (r == null) {
7526                    throw new SecurityException(
7527                            "Unable to find app for caller " + caller
7528                          + " (pid=" + Binder.getCallingPid()
7529                          + ") when getting content provider " + name);
7530                }
7531            }
7532
7533            // First check if this content provider has been published...
7534            cpr = (ContentProviderRecord)mProvidersByName.get(name);
7535            if (cpr != null) {
7536                cpi = cpr.info;
7537                if (checkContentProviderPermissionLocked(cpi, r, -1) != null) {
7538                    return new ContentProviderHolder(cpi,
7539                            cpi.readPermission != null
7540                                    ? cpi.readPermission : cpi.writePermission);
7541                }
7542
7543                if (r != null && cpr.canRunHere(r)) {
7544                    // This provider has been published or is in the process
7545                    // of being published...  but it is also allowed to run
7546                    // in the caller's process, so don't make a connection
7547                    // and just let the caller instantiate its own instance.
7548                    if (cpr.provider != null) {
7549                        // don't give caller the provider object, it needs
7550                        // to make its own.
7551                        cpr = new ContentProviderRecord(cpr);
7552                    }
7553                    return cpr;
7554                }
7555
7556                final long origId = Binder.clearCallingIdentity();
7557
7558                // In this case the provider instance already exists, so we can
7559                // return it right away.
7560                if (r != null) {
7561                    if (DEBUG_PROVIDER) Log.v(TAG,
7562                            "Adding provider requested by "
7563                            + r.processName + " from process "
7564                            + cpr.info.processName);
7565                    Integer cnt = r.conProviders.get(cpr);
7566                    if (cnt == null) {
7567                        r.conProviders.put(cpr, new Integer(1));
7568                    } else {
7569                        r.conProviders.put(cpr, new Integer(cnt.intValue()+1));
7570                    }
7571                    cpr.clients.add(r);
7572                } else {
7573                    cpr.externals++;
7574                }
7575
7576                if (cpr.app != null) {
7577                    updateOomAdjLocked(cpr.app);
7578                }
7579
7580                Binder.restoreCallingIdentity(origId);
7581
7582            } else {
7583                try {
7584                    cpi = ActivityThread.getPackageManager().
7585                        resolveContentProvider(name,
7586                                STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
7587                } catch (RemoteException ex) {
7588                }
7589                if (cpi == null) {
7590                    return null;
7591                }
7592
7593                if (checkContentProviderPermissionLocked(cpi, r, -1) != null) {
7594                    return new ContentProviderHolder(cpi,
7595                            cpi.readPermission != null
7596                                    ? cpi.readPermission : cpi.writePermission);
7597                }
7598
7599                cpr = (ContentProviderRecord)mProvidersByClass.get(cpi.name);
7600                final boolean firstClass = cpr == null;
7601                if (firstClass) {
7602                    try {
7603                        ApplicationInfo ai =
7604                            ActivityThread.getPackageManager().
7605                                getApplicationInfo(
7606                                        cpi.applicationInfo.packageName,
7607                                        STOCK_PM_FLAGS);
7608                        if (ai == null) {
7609                            Log.w(TAG, "No package info for content provider "
7610                                    + cpi.name);
7611                            return null;
7612                        }
7613                        cpr = new ContentProviderRecord(cpi, ai);
7614                    } catch (RemoteException ex) {
7615                        // pm is in same process, this will never happen.
7616                    }
7617                }
7618
7619                if (r != null && cpr.canRunHere(r)) {
7620                    // If this is a multiprocess provider, then just return its
7621                    // info and allow the caller to instantiate it.  Only do
7622                    // this if the provider is the same user as the caller's
7623                    // process, or can run as root (so can be in any process).
7624                    return cpr;
7625                }
7626
7627                if (DEBUG_PROVIDER) {
7628                    RuntimeException e = new RuntimeException("here");
7629                    Log.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.info.uid
7630                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
7631                }
7632
7633                // This is single process, and our app is now connecting to it.
7634                // See if we are already in the process of launching this
7635                // provider.
7636                final int N = mLaunchingProviders.size();
7637                int i;
7638                for (i=0; i<N; i++) {
7639                    if (mLaunchingProviders.get(i) == cpr) {
7640                        break;
7641                    }
7642                }
7643
7644                // If the provider is not already being launched, then get it
7645                // started.
7646                if (i >= N) {
7647                    final long origId = Binder.clearCallingIdentity();
7648                    ProcessRecord proc = startProcessLocked(cpi.processName,
7649                            cpr.appInfo, false, 0, "content provider",
7650                            new ComponentName(cpi.applicationInfo.packageName,
7651                                    cpi.name), false);
7652                    if (proc == null) {
7653                        Log.w(TAG, "Unable to launch app "
7654                                + cpi.applicationInfo.packageName + "/"
7655                                + cpi.applicationInfo.uid + " for provider "
7656                                + name + ": process is bad");
7657                        return null;
7658                    }
7659                    cpr.launchingApp = proc;
7660                    mLaunchingProviders.add(cpr);
7661                    Binder.restoreCallingIdentity(origId);
7662                }
7663
7664                // Make sure the provider is published (the same provider class
7665                // may be published under multiple names).
7666                if (firstClass) {
7667                    mProvidersByClass.put(cpi.name, cpr);
7668                }
7669                mProvidersByName.put(name, cpr);
7670
7671                if (r != null) {
7672                    if (DEBUG_PROVIDER) Log.v(TAG,
7673                            "Adding provider requested by "
7674                            + r.processName + " from process "
7675                            + cpr.info.processName);
7676                    Integer cnt = r.conProviders.get(cpr);
7677                    if (cnt == null) {
7678                        r.conProviders.put(cpr, new Integer(1));
7679                    } else {
7680                        r.conProviders.put(cpr, new Integer(cnt.intValue()+1));
7681                    }
7682                    cpr.clients.add(r);
7683                } else {
7684                    cpr.externals++;
7685                }
7686            }
7687        }
7688
7689        // Wait for the provider to be published...
7690        synchronized (cpr) {
7691            while (cpr.provider == null) {
7692                if (cpr.launchingApp == null) {
7693                    Log.w(TAG, "Unable to launch app "
7694                            + cpi.applicationInfo.packageName + "/"
7695                            + cpi.applicationInfo.uid + " for provider "
7696                            + name + ": launching app became null");
7697                    EventLog.writeEvent(LOG_AM_PROVIDER_LOST_PROCESS,
7698                            cpi.applicationInfo.packageName,
7699                            cpi.applicationInfo.uid, name);
7700                    return null;
7701                }
7702                try {
7703                    cpr.wait();
7704                } catch (InterruptedException ex) {
7705                }
7706            }
7707        }
7708        return cpr;
7709    }
7710
7711    public final ContentProviderHolder getContentProvider(
7712            IApplicationThread caller, String name) {
7713        if (caller == null) {
7714            String msg = "null IApplicationThread when getting content provider "
7715                    + name;
7716            Log.w(TAG, msg);
7717            throw new SecurityException(msg);
7718        }
7719
7720        return getContentProviderImpl(caller, name);
7721    }
7722
7723    private ContentProviderHolder getContentProviderExternal(String name) {
7724        return getContentProviderImpl(null, name);
7725    }
7726
7727    /**
7728     * Drop a content provider from a ProcessRecord's bookkeeping
7729     * @param cpr
7730     */
7731    public void removeContentProvider(IApplicationThread caller, String name) {
7732        synchronized (this) {
7733            ContentProviderRecord cpr = (ContentProviderRecord)mProvidersByName.get(name);
7734            if(cpr == null) {
7735                // remove from mProvidersByClass
7736                if (DEBUG_PROVIDER) Log.v(TAG, name +
7737                        " provider not found in providers list");
7738                return;
7739            }
7740            final ProcessRecord r = getRecordForAppLocked(caller);
7741            if (r == null) {
7742                throw new SecurityException(
7743                        "Unable to find app for caller " + caller +
7744                        " when removing content provider " + name);
7745            }
7746            //update content provider record entry info
7747            ContentProviderRecord localCpr = (ContentProviderRecord)
7748                    mProvidersByClass.get(cpr.info.name);
7749            if (DEBUG_PROVIDER) Log.v(TAG, "Removing provider requested by "
7750                    + r.info.processName + " from process "
7751                    + localCpr.appInfo.processName);
7752            if (localCpr.app == r) {
7753                //should not happen. taken care of as a local provider
7754                Log.w(TAG, "removeContentProvider called on local provider: "
7755                        + cpr.info.name + " in process " + r.processName);
7756                return;
7757            } else {
7758                Integer cnt = r.conProviders.get(localCpr);
7759                if (cnt == null || cnt.intValue() <= 1) {
7760                    localCpr.clients.remove(r);
7761                    r.conProviders.remove(localCpr);
7762                } else {
7763                    r.conProviders.put(localCpr, new Integer(cnt.intValue()-1));
7764                }
7765            }
7766            updateOomAdjLocked();
7767        }
7768    }
7769
7770    private void removeContentProviderExternal(String name) {
7771        synchronized (this) {
7772            ContentProviderRecord cpr = (ContentProviderRecord)mProvidersByName.get(name);
7773            if(cpr == null) {
7774                //remove from mProvidersByClass
7775                if(localLOGV) Log.v(TAG, name+" content provider not found in providers list");
7776                return;
7777            }
7778
7779            //update content provider record entry info
7780            ContentProviderRecord localCpr = (ContentProviderRecord) mProvidersByClass.get(cpr.info.name);
7781            localCpr.externals--;
7782            if (localCpr.externals < 0) {
7783                Log.e(TAG, "Externals < 0 for content provider " + localCpr);
7784            }
7785            updateOomAdjLocked();
7786        }
7787    }
7788
7789    public final void publishContentProviders(IApplicationThread caller,
7790            List<ContentProviderHolder> providers) {
7791        if (providers == null) {
7792            return;
7793        }
7794
7795        synchronized(this) {
7796            final ProcessRecord r = getRecordForAppLocked(caller);
7797            if (r == null) {
7798                throw new SecurityException(
7799                        "Unable to find app for caller " + caller
7800                      + " (pid=" + Binder.getCallingPid()
7801                      + ") when publishing content providers");
7802            }
7803
7804            final long origId = Binder.clearCallingIdentity();
7805
7806            final int N = providers.size();
7807            for (int i=0; i<N; i++) {
7808                ContentProviderHolder src = providers.get(i);
7809                if (src == null || src.info == null || src.provider == null) {
7810                    continue;
7811                }
7812                ContentProviderRecord dst =
7813                    (ContentProviderRecord)r.pubProviders.get(src.info.name);
7814                if (dst != null) {
7815                    mProvidersByClass.put(dst.info.name, dst);
7816                    String names[] = dst.info.authority.split(";");
7817                    for (int j = 0; j < names.length; j++) {
7818                        mProvidersByName.put(names[j], dst);
7819                    }
7820
7821                    int NL = mLaunchingProviders.size();
7822                    int j;
7823                    for (j=0; j<NL; j++) {
7824                        if (mLaunchingProviders.get(j) == dst) {
7825                            mLaunchingProviders.remove(j);
7826                            j--;
7827                            NL--;
7828                        }
7829                    }
7830                    synchronized (dst) {
7831                        dst.provider = src.provider;
7832                        dst.app = r;
7833                        dst.notifyAll();
7834                    }
7835                    updateOomAdjLocked(r);
7836                }
7837            }
7838
7839            Binder.restoreCallingIdentity(origId);
7840        }
7841    }
7842
7843    public static final void installSystemProviders() {
7844        ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
7845        List providers = mSelf.generateApplicationProvidersLocked(app);
7846        mSystemThread.installSystemProviders(providers);
7847    }
7848
7849    // =========================================================
7850    // GLOBAL MANAGEMENT
7851    // =========================================================
7852
7853    final ProcessRecord newProcessRecordLocked(IApplicationThread thread,
7854            ApplicationInfo info, String customProcess) {
7855        String proc = customProcess != null ? customProcess : info.processName;
7856        BatteryStatsImpl.Uid.Proc ps = null;
7857        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
7858        synchronized (stats) {
7859            ps = stats.getProcessStatsLocked(info.uid, proc);
7860        }
7861        return new ProcessRecord(ps, thread, info, proc);
7862    }
7863
7864    final ProcessRecord addAppLocked(ApplicationInfo info) {
7865        ProcessRecord app = getProcessRecordLocked(info.processName, info.uid);
7866
7867        if (app == null) {
7868            app = newProcessRecordLocked(null, info, null);
7869            mProcessNames.put(info.processName, info.uid, app);
7870            updateLRUListLocked(app, true);
7871        }
7872
7873        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
7874                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
7875            app.persistent = true;
7876            app.maxAdj = CORE_SERVER_ADJ;
7877        }
7878        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
7879            mPersistentStartingProcesses.add(app);
7880            startProcessLocked(app, "added application", app.processName);
7881        }
7882
7883        return app;
7884    }
7885
7886    public void unhandledBack() {
7887        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
7888                "unhandledBack()");
7889
7890        synchronized(this) {
7891            int count = mHistory.size();
7892            if (Config.LOGD) Log.d(
7893                TAG, "Performing unhandledBack(): stack size = " + count);
7894            if (count > 1) {
7895                final long origId = Binder.clearCallingIdentity();
7896                finishActivityLocked((HistoryRecord)mHistory.get(count-1),
7897                        count-1, Activity.RESULT_CANCELED, null, "unhandled-back");
7898                Binder.restoreCallingIdentity(origId);
7899            }
7900        }
7901    }
7902
7903    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
7904        String name = uri.getAuthority();
7905        ContentProviderHolder cph = getContentProviderExternal(name);
7906        ParcelFileDescriptor pfd = null;
7907        if (cph != null) {
7908            // We record the binder invoker's uid in thread-local storage before
7909            // going to the content provider to open the file.  Later, in the code
7910            // that handles all permissions checks, we look for this uid and use
7911            // that rather than the Activity Manager's own uid.  The effect is that
7912            // we do the check against the caller's permissions even though it looks
7913            // to the content provider like the Activity Manager itself is making
7914            // the request.
7915            sCallerIdentity.set(new Identity(
7916                    Binder.getCallingPid(), Binder.getCallingUid()));
7917            try {
7918                pfd = cph.provider.openFile(uri, "r");
7919            } catch (FileNotFoundException e) {
7920                // do nothing; pfd will be returned null
7921            } finally {
7922                // Ensure that whatever happens, we clean up the identity state
7923                sCallerIdentity.remove();
7924            }
7925
7926            // We've got the fd now, so we're done with the provider.
7927            removeContentProviderExternal(name);
7928        } else {
7929            Log.d(TAG, "Failed to get provider for authority '" + name + "'");
7930        }
7931        return pfd;
7932    }
7933
7934    public void goingToSleep() {
7935        synchronized(this) {
7936            mSleeping = true;
7937            mWindowManager.setEventDispatching(false);
7938
7939            if (mResumedActivity != null) {
7940                pauseIfSleepingLocked();
7941            } else {
7942                Log.w(TAG, "goingToSleep with no resumed activity!");
7943            }
7944        }
7945    }
7946
7947    public boolean shutdown(int timeout) {
7948        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
7949                != PackageManager.PERMISSION_GRANTED) {
7950            throw new SecurityException("Requires permission "
7951                    + android.Manifest.permission.SHUTDOWN);
7952        }
7953
7954        boolean timedout = false;
7955
7956        synchronized(this) {
7957            mShuttingDown = true;
7958            mWindowManager.setEventDispatching(false);
7959
7960            if (mResumedActivity != null) {
7961                pauseIfSleepingLocked();
7962                final long endTime = System.currentTimeMillis() + timeout;
7963                while (mResumedActivity != null || mPausingActivity != null) {
7964                    long delay = endTime - System.currentTimeMillis();
7965                    if (delay <= 0) {
7966                        Log.w(TAG, "Activity manager shutdown timed out");
7967                        timedout = true;
7968                        break;
7969                    }
7970                    try {
7971                        this.wait();
7972                    } catch (InterruptedException e) {
7973                    }
7974                }
7975            }
7976        }
7977
7978        mUsageStatsService.shutdown();
7979        mBatteryStatsService.shutdown();
7980
7981        return timedout;
7982    }
7983
7984    void pauseIfSleepingLocked() {
7985        if (mSleeping || mShuttingDown) {
7986            if (!mGoingToSleep.isHeld()) {
7987                mGoingToSleep.acquire();
7988                if (mLaunchingActivity.isHeld()) {
7989                    mLaunchingActivity.release();
7990                    mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
7991                }
7992            }
7993
7994            // If we are not currently pausing an activity, get the current
7995            // one to pause.  If we are pausing one, we will just let that stuff
7996            // run and release the wake lock when all done.
7997            if (mPausingActivity == null) {
7998                if (DEBUG_PAUSE) Log.v(TAG, "Sleep needs to pause...");
7999                if (DEBUG_USER_LEAVING) Log.v(TAG, "Sleep => pause with userLeaving=false");
8000                startPausingLocked(false, true);
8001            }
8002        }
8003    }
8004
8005    public void wakingUp() {
8006        synchronized(this) {
8007            if (mGoingToSleep.isHeld()) {
8008                mGoingToSleep.release();
8009            }
8010            mWindowManager.setEventDispatching(true);
8011            mSleeping = false;
8012            resumeTopActivityLocked(null);
8013        }
8014    }
8015
8016    public void stopAppSwitches() {
8017        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8018                != PackageManager.PERMISSION_GRANTED) {
8019            throw new SecurityException("Requires permission "
8020                    + android.Manifest.permission.STOP_APP_SWITCHES);
8021        }
8022
8023        synchronized(this) {
8024            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
8025                    + APP_SWITCH_DELAY_TIME;
8026            mDidAppSwitch = false;
8027            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8028            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8029            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
8030        }
8031    }
8032
8033    public void resumeAppSwitches() {
8034        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8035                != PackageManager.PERMISSION_GRANTED) {
8036            throw new SecurityException("Requires permission "
8037                    + android.Manifest.permission.STOP_APP_SWITCHES);
8038        }
8039
8040        synchronized(this) {
8041            // Note that we don't execute any pending app switches... we will
8042            // let those wait until either the timeout, or the next start
8043            // activity request.
8044            mAppSwitchesAllowedTime = 0;
8045        }
8046    }
8047
8048    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
8049            String name) {
8050        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
8051            return true;
8052        }
8053
8054        final int perm = checkComponentPermission(
8055                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
8056                callingUid, -1);
8057        if (perm == PackageManager.PERMISSION_GRANTED) {
8058            return true;
8059        }
8060
8061        Log.w(TAG, name + " request from " + callingUid + " stopped");
8062        return false;
8063    }
8064
8065    public void setDebugApp(String packageName, boolean waitForDebugger,
8066            boolean persistent) {
8067        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
8068                "setDebugApp()");
8069
8070        // Note that this is not really thread safe if there are multiple
8071        // callers into it at the same time, but that's not a situation we
8072        // care about.
8073        if (persistent) {
8074            final ContentResolver resolver = mContext.getContentResolver();
8075            Settings.System.putString(
8076                resolver, Settings.System.DEBUG_APP,
8077                packageName);
8078            Settings.System.putInt(
8079                resolver, Settings.System.WAIT_FOR_DEBUGGER,
8080                waitForDebugger ? 1 : 0);
8081        }
8082
8083        synchronized (this) {
8084            if (!persistent) {
8085                mOrigDebugApp = mDebugApp;
8086                mOrigWaitForDebugger = mWaitForDebugger;
8087            }
8088            mDebugApp = packageName;
8089            mWaitForDebugger = waitForDebugger;
8090            mDebugTransient = !persistent;
8091            if (packageName != null) {
8092                final long origId = Binder.clearCallingIdentity();
8093                uninstallPackageLocked(packageName, -1, false);
8094                Binder.restoreCallingIdentity(origId);
8095            }
8096        }
8097    }
8098
8099    public void setAlwaysFinish(boolean enabled) {
8100        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
8101                "setAlwaysFinish()");
8102
8103        Settings.System.putInt(
8104                mContext.getContentResolver(),
8105                Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
8106
8107        synchronized (this) {
8108            mAlwaysFinishActivities = enabled;
8109        }
8110    }
8111
8112    public void setActivityController(IActivityController controller) {
8113        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8114                "setActivityController()");
8115        synchronized (this) {
8116            mController = controller;
8117        }
8118    }
8119
8120    public void registerActivityWatcher(IActivityWatcher watcher) {
8121        mWatchers.register(watcher);
8122    }
8123
8124    public void unregisterActivityWatcher(IActivityWatcher watcher) {
8125        mWatchers.unregister(watcher);
8126    }
8127
8128    public final void enterSafeMode() {
8129        synchronized(this) {
8130            // It only makes sense to do this before the system is ready
8131            // and started launching other packages.
8132            if (!mSystemReady) {
8133                try {
8134                    ActivityThread.getPackageManager().enterSafeMode();
8135                } catch (RemoteException e) {
8136                }
8137
8138                View v = LayoutInflater.from(mContext).inflate(
8139                        com.android.internal.R.layout.safe_mode, null);
8140                WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
8141                lp.type = WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY;
8142                lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
8143                lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
8144                lp.gravity = Gravity.BOTTOM | Gravity.LEFT;
8145                lp.format = v.getBackground().getOpacity();
8146                lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
8147                        | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
8148                ((WindowManager)mContext.getSystemService(
8149                        Context.WINDOW_SERVICE)).addView(v, lp);
8150            }
8151        }
8152    }
8153
8154    public void noteWakeupAlarm(IIntentSender sender) {
8155        if (!(sender instanceof PendingIntentRecord)) {
8156            return;
8157        }
8158        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8159        synchronized (stats) {
8160            if (mBatteryStatsService.isOnBattery()) {
8161                mBatteryStatsService.enforceCallingPermission();
8162                PendingIntentRecord rec = (PendingIntentRecord)sender;
8163                int MY_UID = Binder.getCallingUid();
8164                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
8165                BatteryStatsImpl.Uid.Pkg pkg =
8166                    stats.getPackageStatsLocked(uid, rec.key.packageName);
8167                pkg.incWakeupsLocked();
8168            }
8169        }
8170    }
8171
8172    public boolean killPidsForMemory(int[] pids) {
8173        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
8174            throw new SecurityException("killPidsForMemory only available to the system");
8175        }
8176
8177        // XXX Note: don't acquire main activity lock here, because the window
8178        // manager calls in with its locks held.
8179
8180        boolean killed = false;
8181        synchronized (mPidsSelfLocked) {
8182            int[] types = new int[pids.length];
8183            int worstType = 0;
8184            for (int i=0; i<pids.length; i++) {
8185                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
8186                if (proc != null) {
8187                    int type = proc.setAdj;
8188                    types[i] = type;
8189                    if (type > worstType) {
8190                        worstType = type;
8191                    }
8192                }
8193            }
8194
8195            // If the worse oom_adj is somewhere in the hidden proc LRU range,
8196            // then constrain it so we will kill all hidden procs.
8197            if (worstType < EMPTY_APP_ADJ && worstType > HIDDEN_APP_MIN_ADJ) {
8198                worstType = HIDDEN_APP_MIN_ADJ;
8199            }
8200            Log.w(TAG, "Killing processes for memory at adjustment " + worstType);
8201            for (int i=0; i<pids.length; i++) {
8202                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
8203                if (proc == null) {
8204                    continue;
8205                }
8206                int adj = proc.setAdj;
8207                if (adj >= worstType) {
8208                    Log.w(TAG, "Killing for memory: " + proc + " (adj "
8209                            + adj + ")");
8210                    EventLog.writeEvent(LOG_AM_KILL_FOR_MEMORY, proc.pid,
8211                            proc.processName, adj);
8212                    killed = true;
8213                    Process.killProcess(pids[i]);
8214                }
8215            }
8216        }
8217        return killed;
8218    }
8219
8220    public void reportPss(IApplicationThread caller, int pss) {
8221        Watchdog.PssRequestor req;
8222        String name;
8223        ProcessRecord callerApp;
8224        synchronized (this) {
8225            if (caller == null) {
8226                return;
8227            }
8228            callerApp = getRecordForAppLocked(caller);
8229            if (callerApp == null) {
8230                return;
8231            }
8232            callerApp.lastPss = pss;
8233            req = callerApp;
8234            name = callerApp.processName;
8235        }
8236        Watchdog.getInstance().reportPss(req, name, pss);
8237        if (!callerApp.persistent) {
8238            removeRequestedPss(callerApp);
8239        }
8240    }
8241
8242    public void requestPss(Runnable completeCallback) {
8243        ArrayList<ProcessRecord> procs;
8244        synchronized (this) {
8245            mRequestPssCallback = completeCallback;
8246            mRequestPssList.clear();
8247            for (int i=mLRUProcesses.size()-1; i>=0; i--) {
8248                ProcessRecord proc = mLRUProcesses.get(i);
8249                if (!proc.persistent) {
8250                    mRequestPssList.add(proc);
8251                }
8252            }
8253            procs = new ArrayList<ProcessRecord>(mRequestPssList);
8254        }
8255
8256        int oldPri = Process.getThreadPriority(Process.myTid());
8257        Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
8258        for (int i=procs.size()-1; i>=0; i--) {
8259            ProcessRecord proc = procs.get(i);
8260            proc.lastPss = 0;
8261            proc.requestPss();
8262        }
8263        Process.setThreadPriority(oldPri);
8264    }
8265
8266    void removeRequestedPss(ProcessRecord proc) {
8267        Runnable callback = null;
8268        synchronized (this) {
8269            if (mRequestPssList.remove(proc)) {
8270                if (mRequestPssList.size() == 0) {
8271                    callback = mRequestPssCallback;
8272                    mRequestPssCallback = null;
8273                }
8274            }
8275        }
8276
8277        if (callback != null) {
8278            callback.run();
8279        }
8280    }
8281
8282    public void collectPss(Watchdog.PssStats stats) {
8283        stats.mEmptyPss = 0;
8284        stats.mEmptyCount = 0;
8285        stats.mBackgroundPss = 0;
8286        stats.mBackgroundCount = 0;
8287        stats.mServicePss = 0;
8288        stats.mServiceCount = 0;
8289        stats.mVisiblePss = 0;
8290        stats.mVisibleCount = 0;
8291        stats.mForegroundPss = 0;
8292        stats.mForegroundCount = 0;
8293        stats.mNoPssCount = 0;
8294        synchronized (this) {
8295            int i;
8296            int NPD = mProcDeaths.length < stats.mProcDeaths.length
8297                    ? mProcDeaths.length : stats.mProcDeaths.length;
8298            int aggr = 0;
8299            for (i=0; i<NPD; i++) {
8300                aggr += mProcDeaths[i];
8301                stats.mProcDeaths[i] = aggr;
8302            }
8303            while (i<stats.mProcDeaths.length) {
8304                stats.mProcDeaths[i] = 0;
8305                i++;
8306            }
8307
8308            for (i=mLRUProcesses.size()-1; i>=0; i--) {
8309                ProcessRecord proc = mLRUProcesses.get(i);
8310                if (proc.persistent) {
8311                    continue;
8312                }
8313                //Log.i(TAG, "Proc " + proc + ": pss=" + proc.lastPss);
8314                if (proc.lastPss == 0) {
8315                    stats.mNoPssCount++;
8316                    continue;
8317                }
8318                if (proc.setAdj == EMPTY_APP_ADJ) {
8319                    stats.mEmptyPss += proc.lastPss;
8320                    stats.mEmptyCount++;
8321                } else if (proc.setAdj == CONTENT_PROVIDER_ADJ) {
8322                    stats.mEmptyPss += proc.lastPss;
8323                    stats.mEmptyCount++;
8324                } else if (proc.setAdj >= HIDDEN_APP_MIN_ADJ) {
8325                    stats.mBackgroundPss += proc.lastPss;
8326                    stats.mBackgroundCount++;
8327                } else if (proc.setAdj >= VISIBLE_APP_ADJ) {
8328                    stats.mVisiblePss += proc.lastPss;
8329                    stats.mVisibleCount++;
8330                } else {
8331                    stats.mForegroundPss += proc.lastPss;
8332                    stats.mForegroundCount++;
8333                }
8334            }
8335        }
8336    }
8337
8338    public final void startRunning(String pkg, String cls, String action,
8339            String data) {
8340        synchronized(this) {
8341            if (mStartRunning) {
8342                return;
8343            }
8344            mStartRunning = true;
8345            mTopComponent = pkg != null && cls != null
8346                    ? new ComponentName(pkg, cls) : null;
8347            mTopAction = action != null ? action : Intent.ACTION_MAIN;
8348            mTopData = data;
8349            if (!mSystemReady) {
8350                return;
8351            }
8352        }
8353
8354        systemReady(null);
8355    }
8356
8357    private void retrieveSettings() {
8358        final ContentResolver resolver = mContext.getContentResolver();
8359        String debugApp = Settings.System.getString(
8360            resolver, Settings.System.DEBUG_APP);
8361        boolean waitForDebugger = Settings.System.getInt(
8362            resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0;
8363        boolean alwaysFinishActivities = Settings.System.getInt(
8364            resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
8365
8366        Configuration configuration = new Configuration();
8367        Settings.System.getConfiguration(resolver, configuration);
8368
8369        synchronized (this) {
8370            mDebugApp = mOrigDebugApp = debugApp;
8371            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
8372            mAlwaysFinishActivities = alwaysFinishActivities;
8373            // This happens before any activities are started, so we can
8374            // change mConfiguration in-place.
8375            mConfiguration.updateFrom(configuration);
8376            if (DEBUG_CONFIGURATION) Log.v(TAG, "Initial config: " + mConfiguration);
8377        }
8378    }
8379
8380    public boolean testIsSystemReady() {
8381        // no need to synchronize(this) just to read & return the value
8382        return mSystemReady;
8383    }
8384
8385    public void systemReady(final Runnable goingCallback) {
8386        // In the simulator, startRunning will never have been called, which
8387        // normally sets a few crucial variables. Do it here instead.
8388        if (!Process.supportsProcesses()) {
8389            mStartRunning = true;
8390            mTopAction = Intent.ACTION_MAIN;
8391        }
8392
8393        synchronized(this) {
8394            if (mSystemReady) {
8395                if (goingCallback != null) goingCallback.run();
8396                return;
8397            }
8398
8399            // Check to see if there are any update receivers to run.
8400            if (!mDidUpdate) {
8401                if (mWaitingUpdate) {
8402                    return;
8403                }
8404                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
8405                List<ResolveInfo> ris = null;
8406                try {
8407                    ris = ActivityThread.getPackageManager().queryIntentReceivers(
8408                                intent, null, 0);
8409                } catch (RemoteException e) {
8410                }
8411                if (ris != null) {
8412                    for (int i=ris.size()-1; i>=0; i--) {
8413                        if ((ris.get(i).activityInfo.applicationInfo.flags
8414                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
8415                            ris.remove(i);
8416                        }
8417                    }
8418                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
8419                    for (int i=0; i<ris.size(); i++) {
8420                        ActivityInfo ai = ris.get(i).activityInfo;
8421                        intent.setComponent(new ComponentName(ai.packageName, ai.name));
8422                        IIntentReceiver finisher = null;
8423                        if (i == 0) {
8424                            finisher = new IIntentReceiver.Stub() {
8425                                public void performReceive(Intent intent, int resultCode,
8426                                        String data, Bundle extras, boolean ordered,
8427                                        boolean sticky)
8428                                        throws RemoteException {
8429                                    synchronized (ActivityManagerService.this) {
8430                                        mDidUpdate = true;
8431                                    }
8432                                    systemReady(goingCallback);
8433                                }
8434                            };
8435                        }
8436                        Log.i(TAG, "Sending system update to: " + intent.getComponent());
8437                        broadcastIntentLocked(null, null, intent, null, finisher,
8438                                0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID);
8439                        if (i == 0) {
8440                            mWaitingUpdate = true;
8441                        }
8442                    }
8443                }
8444                if (mWaitingUpdate) {
8445                    return;
8446                }
8447                mDidUpdate = true;
8448            }
8449
8450            mSystemReady = true;
8451            if (!mStartRunning) {
8452                return;
8453            }
8454        }
8455
8456        ArrayList<ProcessRecord> procsToKill = null;
8457        synchronized(mPidsSelfLocked) {
8458            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
8459                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
8460                if (!isAllowedWhileBooting(proc.info)){
8461                    if (procsToKill == null) {
8462                        procsToKill = new ArrayList<ProcessRecord>();
8463                    }
8464                    procsToKill.add(proc);
8465                }
8466            }
8467        }
8468
8469        if (procsToKill != null) {
8470            synchronized(this) {
8471                for (int i=procsToKill.size()-1; i>=0; i--) {
8472                    ProcessRecord proc = procsToKill.get(i);
8473                    Log.i(TAG, "Removing system update proc: " + proc);
8474                    removeProcessLocked(proc, true);
8475                }
8476            }
8477        }
8478
8479        Log.i(TAG, "System now ready");
8480        EventLog.writeEvent(LOG_BOOT_PROGRESS_AMS_READY,
8481            SystemClock.uptimeMillis());
8482
8483        synchronized(this) {
8484            // Make sure we have no pre-ready processes sitting around.
8485
8486            if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
8487                ResolveInfo ri = mContext.getPackageManager()
8488                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
8489                                STOCK_PM_FLAGS);
8490                CharSequence errorMsg = null;
8491                if (ri != null) {
8492                    ActivityInfo ai = ri.activityInfo;
8493                    ApplicationInfo app = ai.applicationInfo;
8494                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
8495                        mTopAction = Intent.ACTION_FACTORY_TEST;
8496                        mTopData = null;
8497                        mTopComponent = new ComponentName(app.packageName,
8498                                ai.name);
8499                    } else {
8500                        errorMsg = mContext.getResources().getText(
8501                                com.android.internal.R.string.factorytest_not_system);
8502                    }
8503                } else {
8504                    errorMsg = mContext.getResources().getText(
8505                            com.android.internal.R.string.factorytest_no_action);
8506                }
8507                if (errorMsg != null) {
8508                    mTopAction = null;
8509                    mTopData = null;
8510                    mTopComponent = null;
8511                    Message msg = Message.obtain();
8512                    msg.what = SHOW_FACTORY_ERROR_MSG;
8513                    msg.getData().putCharSequence("msg", errorMsg);
8514                    mHandler.sendMessage(msg);
8515                }
8516            }
8517        }
8518
8519        retrieveSettings();
8520
8521        if (goingCallback != null) goingCallback.run();
8522
8523        synchronized (this) {
8524            if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
8525                try {
8526                    List apps = ActivityThread.getPackageManager().
8527                        getPersistentApplications(STOCK_PM_FLAGS);
8528                    if (apps != null) {
8529                        int N = apps.size();
8530                        int i;
8531                        for (i=0; i<N; i++) {
8532                            ApplicationInfo info
8533                                = (ApplicationInfo)apps.get(i);
8534                            if (info != null &&
8535                                    !info.packageName.equals("android")) {
8536                                addAppLocked(info);
8537                            }
8538                        }
8539                    }
8540                } catch (RemoteException ex) {
8541                    // pm is in same process, this will never happen.
8542                }
8543            }
8544
8545            // Start up initial activity.
8546            mBooting = true;
8547
8548            try {
8549                if (ActivityThread.getPackageManager().hasSystemUidErrors()) {
8550                    Message msg = Message.obtain();
8551                    msg.what = SHOW_UID_ERROR_MSG;
8552                    mHandler.sendMessage(msg);
8553                }
8554            } catch (RemoteException e) {
8555            }
8556
8557            resumeTopActivityLocked(null);
8558        }
8559    }
8560
8561    boolean makeAppCrashingLocked(ProcessRecord app,
8562            String tag, String shortMsg, String longMsg, byte[] crashData) {
8563        app.crashing = true;
8564        app.crashingReport = generateProcessError(app,
8565                ActivityManager.ProcessErrorStateInfo.CRASHED, tag, shortMsg, longMsg, crashData);
8566        startAppProblemLocked(app);
8567        app.stopFreezingAllLocked();
8568        return handleAppCrashLocked(app);
8569    }
8570
8571    private ComponentName getErrorReportReceiver(ProcessRecord app) {
8572        // check if error reporting is enabled in Gservices
8573        int enabled = Settings.Gservices.getInt(mContext.getContentResolver(),
8574                Settings.Gservices.SEND_ACTION_APP_ERROR, 0);
8575        if (enabled == 0) {
8576            return null;
8577        }
8578
8579        IPackageManager pm = ActivityThread.getPackageManager();
8580
8581        try {
8582            // look for receiver in the installer package
8583            String candidate = pm.getInstallerPackageName(app.info.packageName);
8584            ComponentName result = getErrorReportReceiver(pm, app.info.packageName, candidate);
8585            if (result != null) {
8586                return result;
8587            }
8588
8589            // if the error app is on the system image, look for system apps
8590            // error receiver
8591            if ((app.info.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
8592                candidate = SystemProperties.get(SYSTEM_APPS_ERROR_RECEIVER_PROPERTY);
8593                result = getErrorReportReceiver(pm, app.info.packageName, candidate);
8594                if (result != null) {
8595                    return result;
8596                }
8597            }
8598
8599            // if there is a default receiver, try that
8600            candidate = SystemProperties.get(DEFAULT_ERROR_RECEIVER_PROPERTY);
8601            return getErrorReportReceiver(pm, app.info.packageName, candidate);
8602        } catch (RemoteException e) {
8603            // should not happen
8604            Log.e(TAG, "error talking to PackageManager", e);
8605            return null;
8606        }
8607    }
8608
8609    /**
8610     * Return activity in receiverPackage that handles ACTION_APP_ERROR.
8611     *
8612     * @param pm PackageManager isntance
8613     * @param errorPackage package which caused the error
8614     * @param receiverPackage candidate package to receive the error
8615     * @return activity component within receiverPackage which handles
8616     * ACTION_APP_ERROR, or null if not found
8617     */
8618    private ComponentName getErrorReportReceiver(IPackageManager pm, String errorPackage,
8619            String receiverPackage) throws RemoteException {
8620        if (receiverPackage == null || receiverPackage.length() == 0) {
8621            return null;
8622        }
8623
8624        // break the loop if it's the error report receiver package that crashed
8625        if (receiverPackage.equals(errorPackage)) {
8626            return null;
8627        }
8628
8629        Intent intent = new Intent(Intent.ACTION_APP_ERROR);
8630        intent.setPackage(receiverPackage);
8631        ResolveInfo info = pm.resolveIntent(intent, null, 0);
8632        if (info == null || info.activityInfo == null) {
8633            return null;
8634        }
8635        return new ComponentName(receiverPackage, info.activityInfo.name);
8636    }
8637
8638    void makeAppNotRespondingLocked(ProcessRecord app,
8639            String tag, String shortMsg, String longMsg, byte[] crashData) {
8640        app.notResponding = true;
8641        app.notRespondingReport = generateProcessError(app,
8642                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, tag, shortMsg, longMsg,
8643                crashData);
8644        startAppProblemLocked(app);
8645        app.stopFreezingAllLocked();
8646    }
8647
8648    /**
8649     * Generate a process error record, suitable for attachment to a ProcessRecord.
8650     *
8651     * @param app The ProcessRecord in which the error occurred.
8652     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
8653     *                      ActivityManager.AppErrorStateInfo
8654     * @param tag The tag that was passed into handleApplicationError().  Typically the classname.
8655     * @param shortMsg Short message describing the crash.
8656     * @param longMsg Long message describing the crash.
8657     * @param crashData Raw data passed into handleApplicationError().  Typically a stack trace.
8658     *
8659     * @return Returns a fully-formed AppErrorStateInfo record.
8660     */
8661    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
8662            int condition, String tag, String shortMsg, String longMsg, byte[] crashData) {
8663        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
8664
8665        report.condition = condition;
8666        report.processName = app.processName;
8667        report.pid = app.pid;
8668        report.uid = app.info.uid;
8669        report.tag = tag;
8670        report.shortMsg = shortMsg;
8671        report.longMsg = longMsg;
8672        report.crashData = crashData;
8673
8674        return report;
8675    }
8676
8677    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog,
8678            boolean crashed) {
8679        synchronized (this) {
8680            app.crashing = false;
8681            app.crashingReport = null;
8682            app.notResponding = false;
8683            app.notRespondingReport = null;
8684            if (app.anrDialog == fromDialog) {
8685                app.anrDialog = null;
8686            }
8687            if (app.waitDialog == fromDialog) {
8688                app.waitDialog = null;
8689            }
8690            if (app.pid > 0 && app.pid != MY_PID) {
8691                if (crashed) {
8692                    handleAppCrashLocked(app);
8693                }
8694                Log.i(ActivityManagerService.TAG, "Killing process "
8695                        + app.processName
8696                        + " (pid=" + app.pid + ") at user's request");
8697                Process.killProcess(app.pid);
8698            }
8699
8700        }
8701    }
8702
8703    boolean handleAppCrashLocked(ProcessRecord app) {
8704        long now = SystemClock.uptimeMillis();
8705
8706        Long crashTime = mProcessCrashTimes.get(app.info.processName,
8707                app.info.uid);
8708        if (crashTime != null && now < crashTime+MIN_CRASH_INTERVAL) {
8709            // This process loses!
8710            Log.w(TAG, "Process " + app.info.processName
8711                    + " has crashed too many times: killing!");
8712            EventLog.writeEvent(LOG_AM_PROCESS_CRASHED_TOO_MUCH,
8713                    app.info.processName, app.info.uid);
8714            killServicesLocked(app, false);
8715            for (int i=mHistory.size()-1; i>=0; i--) {
8716                HistoryRecord r = (HistoryRecord)mHistory.get(i);
8717                if (r.app == app) {
8718                    if (Config.LOGD) Log.d(
8719                        TAG, "  Force finishing activity "
8720                        + r.intent.getComponent().flattenToShortString());
8721                    finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed");
8722                }
8723            }
8724            if (!app.persistent) {
8725                // We don't want to start this process again until the user
8726                // explicitly does so...  but for persistent process, we really
8727                // need to keep it running.  If a persistent process is actually
8728                // repeatedly crashing, then badness for everyone.
8729                EventLog.writeEvent(LOG_AM_PROCESS_BAD, app.info.uid,
8730                        app.info.processName);
8731                mBadProcesses.put(app.info.processName, app.info.uid, now);
8732                app.bad = true;
8733                mProcessCrashTimes.remove(app.info.processName, app.info.uid);
8734                app.removed = true;
8735                removeProcessLocked(app, false);
8736                return false;
8737            }
8738        }
8739
8740        // Bump up the crash count of any services currently running in the proc.
8741        if (app.services.size() != 0) {
8742            // Any services running in the application need to be placed
8743            // back in the pending list.
8744            Iterator it = app.services.iterator();
8745            while (it.hasNext()) {
8746                ServiceRecord sr = (ServiceRecord)it.next();
8747                sr.crashCount++;
8748            }
8749        }
8750
8751        mProcessCrashTimes.put(app.info.processName, app.info.uid, now);
8752        return true;
8753    }
8754
8755    void startAppProblemLocked(ProcessRecord app) {
8756        app.errorReportReceiver = getErrorReportReceiver(app);
8757        skipCurrentReceiverLocked(app);
8758    }
8759
8760    void skipCurrentReceiverLocked(ProcessRecord app) {
8761        boolean reschedule = false;
8762        BroadcastRecord r = app.curReceiver;
8763        if (r != null) {
8764            // The current broadcast is waiting for this app's receiver
8765            // to be finished.  Looks like that's not going to happen, so
8766            // let the broadcast continue.
8767            logBroadcastReceiverDiscard(r);
8768            finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
8769                    r.resultExtras, r.resultAbort, true);
8770            reschedule = true;
8771        }
8772        r = mPendingBroadcast;
8773        if (r != null && r.curApp == app) {
8774            if (DEBUG_BROADCAST) Log.v(TAG,
8775                    "skip & discard pending app " + r);
8776            logBroadcastReceiverDiscard(r);
8777            finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
8778                    r.resultExtras, r.resultAbort, true);
8779            reschedule = true;
8780        }
8781        if (reschedule) {
8782            scheduleBroadcastsLocked();
8783        }
8784    }
8785
8786    public int handleApplicationError(IBinder app, int flags,
8787            String tag, String shortMsg, String longMsg, byte[] crashData) {
8788        AppErrorResult result = new AppErrorResult();
8789        ProcessRecord r = null;
8790        synchronized (this) {
8791            if (app != null) {
8792                for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
8793                    final int NA = apps.size();
8794                    for (int ia=0; ia<NA; ia++) {
8795                        ProcessRecord p = apps.valueAt(ia);
8796                        if (p.thread != null && p.thread.asBinder() == app) {
8797                            r = p;
8798                            break;
8799                        }
8800                    }
8801                }
8802            }
8803
8804            if (r != null) {
8805                // The application has crashed. Send the SIGQUIT to the process so
8806                // that it can dump its state.
8807                Process.sendSignal(r.pid, Process.SIGNAL_QUIT);
8808                //Log.i(TAG, "Current system threads:");
8809                //Process.sendSignal(MY_PID, Process.SIGNAL_QUIT);
8810            }
8811
8812            if (mController != null) {
8813                try {
8814                    String name = r != null ? r.processName : null;
8815                    int pid = r != null ? r.pid : Binder.getCallingPid();
8816                    if (!mController.appCrashed(name, pid,
8817                            shortMsg, longMsg, crashData)) {
8818                        Log.w(TAG, "Force-killing crashed app " + name
8819                                + " at watcher's request");
8820                        Process.killProcess(pid);
8821                        return 0;
8822                    }
8823                } catch (RemoteException e) {
8824                    mController = null;
8825                }
8826            }
8827
8828            final long origId = Binder.clearCallingIdentity();
8829
8830            // If this process is running instrumentation, finish it.
8831            if (r != null && r.instrumentationClass != null) {
8832                Log.w(TAG, "Error in app " + r.processName
8833                      + " running instrumentation " + r.instrumentationClass + ":");
8834                if (shortMsg != null) Log.w(TAG, "  " + shortMsg);
8835                if (longMsg != null) Log.w(TAG, "  " + longMsg);
8836                Bundle info = new Bundle();
8837                info.putString("shortMsg", shortMsg);
8838                info.putString("longMsg", longMsg);
8839                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
8840                Binder.restoreCallingIdentity(origId);
8841                return 0;
8842            }
8843
8844            if (r != null) {
8845                if (!makeAppCrashingLocked(r, tag, shortMsg, longMsg, crashData)) {
8846                    return 0;
8847                }
8848            } else {
8849                Log.w(TAG, "Some application object " + app + " tag " + tag
8850                        + " has crashed, but I don't know who it is.");
8851                Log.w(TAG, "ShortMsg:" + shortMsg);
8852                Log.w(TAG, "LongMsg:" + longMsg);
8853                Binder.restoreCallingIdentity(origId);
8854                return 0;
8855            }
8856
8857            Message msg = Message.obtain();
8858            msg.what = SHOW_ERROR_MSG;
8859            HashMap data = new HashMap();
8860            data.put("result", result);
8861            data.put("app", r);
8862            data.put("flags", flags);
8863            data.put("shortMsg", shortMsg);
8864            data.put("longMsg", longMsg);
8865            if (r != null && (r.info.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
8866                // For system processes, submit crash data to the server.
8867                data.put("crashData", crashData);
8868            }
8869            msg.obj = data;
8870            mHandler.sendMessage(msg);
8871
8872            Binder.restoreCallingIdentity(origId);
8873        }
8874
8875        int res = result.get();
8876
8877        Intent appErrorIntent = null;
8878        synchronized (this) {
8879            if (r != null) {
8880                mProcessCrashTimes.put(r.info.processName, r.info.uid,
8881                        SystemClock.uptimeMillis());
8882            }
8883            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
8884                appErrorIntent = createAppErrorIntentLocked(r);
8885                res = AppErrorDialog.FORCE_QUIT;
8886            }
8887        }
8888
8889        if (appErrorIntent != null) {
8890            try {
8891                mContext.startActivity(appErrorIntent);
8892            } catch (ActivityNotFoundException e) {
8893                Log.w(TAG, "bug report receiver dissappeared", e);
8894            }
8895        }
8896
8897        return res;
8898    }
8899
8900    Intent createAppErrorIntentLocked(ProcessRecord r) {
8901        ApplicationErrorReport report = createAppErrorReportLocked(r);
8902        if (report == null) {
8903            return null;
8904        }
8905        Intent result = new Intent(Intent.ACTION_APP_ERROR);
8906        result.setComponent(r.errorReportReceiver);
8907        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
8908        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8909        return result;
8910    }
8911
8912    ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r) {
8913        if (r.errorReportReceiver == null) {
8914            return null;
8915        }
8916
8917        if (!r.crashing && !r.notResponding) {
8918            return null;
8919        }
8920
8921        try {
8922            ApplicationErrorReport report = new ApplicationErrorReport();
8923            report.packageName = r.info.packageName;
8924            report.installerPackageName = r.errorReportReceiver.getPackageName();
8925            report.processName = r.processName;
8926
8927            if (r.crashing) {
8928                report.type = ApplicationErrorReport.TYPE_CRASH;
8929                report.crashInfo = new ApplicationErrorReport.CrashInfo();
8930
8931                ByteArrayInputStream byteStream = new ByteArrayInputStream(
8932                        r.crashingReport.crashData);
8933                DataInputStream dataStream = new DataInputStream(byteStream);
8934                CrashData crashData = new CrashData(dataStream);
8935                ThrowableData throwData = crashData.getThrowableData();
8936
8937                report.time = crashData.getTime();
8938                report.crashInfo.stackTrace = throwData.toString();
8939
8940                // Extract the source of the exception, useful for report
8941                // clustering. Also extract the "deepest" non-null exception
8942                // message.
8943                String exceptionMessage = throwData.getMessage();
8944                while (throwData.getCause() != null) {
8945                    throwData = throwData.getCause();
8946                    String msg = throwData.getMessage();
8947                    if (msg != null && msg.length() > 0) {
8948                       exceptionMessage = msg;
8949                    }
8950                }
8951                StackTraceElementData trace = throwData.getStackTrace()[0];
8952                report.crashInfo.exceptionMessage = exceptionMessage;
8953                report.crashInfo.exceptionClassName = throwData.getType();
8954                report.crashInfo.throwFileName = trace.getFileName();
8955                report.crashInfo.throwClassName = trace.getClassName();
8956                report.crashInfo.throwMethodName = trace.getMethodName();
8957                report.crashInfo.throwLineNumber = trace.getLineNumber();
8958            } else if (r.notResponding) {
8959                report.type = ApplicationErrorReport.TYPE_ANR;
8960                report.anrInfo = new ApplicationErrorReport.AnrInfo();
8961
8962                report.anrInfo.activity = r.notRespondingReport.tag;
8963                report.anrInfo.cause = r.notRespondingReport.shortMsg;
8964                report.anrInfo.info = r.notRespondingReport.longMsg;
8965            }
8966
8967            return report;
8968        } catch (IOException e) {
8969            // we don't send it
8970        }
8971
8972        return null;
8973    }
8974
8975    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
8976        // assume our apps are happy - lazy create the list
8977        List<ActivityManager.ProcessErrorStateInfo> errList = null;
8978
8979        synchronized (this) {
8980
8981            // iterate across all processes
8982            final int N = mLRUProcesses.size();
8983            for (int i = 0; i < N; i++) {
8984                ProcessRecord app = mLRUProcesses.get(i);
8985                if ((app.thread != null) && (app.crashing || app.notResponding)) {
8986                    // This one's in trouble, so we'll generate a report for it
8987                    // crashes are higher priority (in case there's a crash *and* an anr)
8988                    ActivityManager.ProcessErrorStateInfo report = null;
8989                    if (app.crashing) {
8990                        report = app.crashingReport;
8991                    } else if (app.notResponding) {
8992                        report = app.notRespondingReport;
8993                    }
8994
8995                    if (report != null) {
8996                        if (errList == null) {
8997                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
8998                        }
8999                        errList.add(report);
9000                    } else {
9001                        Log.w(TAG, "Missing app error report, app = " + app.processName +
9002                                " crashing = " + app.crashing +
9003                                " notResponding = " + app.notResponding);
9004                    }
9005                }
9006            }
9007        }
9008
9009        return errList;
9010    }
9011
9012    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
9013        // Lazy instantiation of list
9014        List<ActivityManager.RunningAppProcessInfo> runList = null;
9015        synchronized (this) {
9016            // Iterate across all processes
9017            final int N = mLRUProcesses.size();
9018            for (int i = 0; i < N; i++) {
9019                ProcessRecord app = mLRUProcesses.get(i);
9020                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
9021                    // Generate process state info for running application
9022                    ActivityManager.RunningAppProcessInfo currApp =
9023                        new ActivityManager.RunningAppProcessInfo(app.processName,
9024                                app.pid, app.getPackageList());
9025                    currApp.uid = app.info.uid;
9026                    int adj = app.curAdj;
9027                    if (adj >= CONTENT_PROVIDER_ADJ) {
9028                        currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_EMPTY;
9029                    } else if (adj >= HIDDEN_APP_MIN_ADJ) {
9030                        currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
9031                        currApp.lru = adj - HIDDEN_APP_MIN_ADJ + 1;
9032                    } else if (adj >= HOME_APP_ADJ) {
9033                        currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
9034                        currApp.lru = 0;
9035                    } else if (adj >= SECONDARY_SERVER_ADJ) {
9036                        currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
9037                    } else if (adj >= VISIBLE_APP_ADJ) {
9038                        currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
9039                    } else {
9040                        currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
9041                    }
9042                    currApp.importanceReasonCode = app.adjTypeCode;
9043                    if (app.adjSource instanceof ProcessRecord) {
9044                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
9045                    } else if (app.adjSource instanceof HistoryRecord) {
9046                        HistoryRecord r = (HistoryRecord)app.adjSource;
9047                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
9048                    }
9049                    if (app.adjTarget instanceof ComponentName) {
9050                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
9051                    }
9052                    //Log.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
9053                    //        + " lru=" + currApp.lru);
9054                    if (runList == null) {
9055                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
9056                    }
9057                    runList.add(currApp);
9058                }
9059            }
9060        }
9061        return runList;
9062    }
9063
9064    @Override
9065    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
9066        synchronized (this) {
9067            if (checkCallingPermission(android.Manifest.permission.DUMP)
9068                    != PackageManager.PERMISSION_GRANTED) {
9069                pw.println("Permission Denial: can't dump ActivityManager from from pid="
9070                        + Binder.getCallingPid()
9071                        + ", uid=" + Binder.getCallingUid()
9072                        + " without permission "
9073                        + android.Manifest.permission.DUMP);
9074                return;
9075            }
9076            if (args.length != 0 && "service".equals(args[0])) {
9077                dumpService(fd, pw, args);
9078                return;
9079            }
9080            pw.println("Activities in Current Activity Manager State:");
9081            dumpHistoryList(pw, mHistory, "  ", "Hist", true);
9082            pw.println(" ");
9083            pw.println("  Running activities (most recent first):");
9084            dumpHistoryList(pw, mLRUActivities, "  ", "Run", false);
9085            if (mWaitingVisibleActivities.size() > 0) {
9086                pw.println(" ");
9087                pw.println("  Activities waiting for another to become visible:");
9088                dumpHistoryList(pw, mWaitingVisibleActivities, "  ", "Wait", false);
9089            }
9090            if (mStoppingActivities.size() > 0) {
9091                pw.println(" ");
9092                pw.println("  Activities waiting to stop:");
9093                dumpHistoryList(pw, mStoppingActivities, "  ", "Stop", false);
9094            }
9095            if (mFinishingActivities.size() > 0) {
9096                pw.println(" ");
9097                pw.println("  Activities waiting to finish:");
9098                dumpHistoryList(pw, mFinishingActivities, "  ", "Fin", false);
9099            }
9100
9101            pw.println(" ");
9102            pw.println("  mPausingActivity: " + mPausingActivity);
9103            pw.println("  mResumedActivity: " + mResumedActivity);
9104            pw.println("  mFocusedActivity: " + mFocusedActivity);
9105            pw.println("  mLastPausedActivity: " + mLastPausedActivity);
9106
9107            if (mRecentTasks.size() > 0) {
9108                pw.println(" ");
9109                pw.println("Recent tasks in Current Activity Manager State:");
9110
9111                final int N = mRecentTasks.size();
9112                for (int i=0; i<N; i++) {
9113                    TaskRecord tr = mRecentTasks.get(i);
9114                    pw.print("  * Recent #"); pw.print(i); pw.print(": ");
9115                            pw.println(tr);
9116                    mRecentTasks.get(i).dump(pw, "    ");
9117                }
9118            }
9119
9120            pw.println(" ");
9121            pw.println("  mCurTask: " + mCurTask);
9122
9123            pw.println(" ");
9124            pw.println("Processes in Current Activity Manager State:");
9125
9126            boolean needSep = false;
9127            int numPers = 0;
9128
9129            for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
9130                final int NA = procs.size();
9131                for (int ia=0; ia<NA; ia++) {
9132                    if (!needSep) {
9133                        pw.println("  All known processes:");
9134                        needSep = true;
9135                    }
9136                    ProcessRecord r = procs.valueAt(ia);
9137                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
9138                        pw.print(" UID "); pw.print(procs.keyAt(ia));
9139                        pw.print(" "); pw.println(r);
9140                    r.dump(pw, "    ");
9141                    if (r.persistent) {
9142                        numPers++;
9143                    }
9144                }
9145            }
9146
9147            if (mLRUProcesses.size() > 0) {
9148                if (needSep) pw.println(" ");
9149                needSep = true;
9150                pw.println("  Running processes (most recent first):");
9151                dumpProcessList(pw, mLRUProcesses, "    ",
9152                        "App ", "PERS", true);
9153                needSep = true;
9154            }
9155
9156            synchronized (mPidsSelfLocked) {
9157                if (mPidsSelfLocked.size() > 0) {
9158                    if (needSep) pw.println(" ");
9159                    needSep = true;
9160                    pw.println("  PID mappings:");
9161                    for (int i=0; i<mPidsSelfLocked.size(); i++) {
9162                        pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
9163                            pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
9164                    }
9165                }
9166            }
9167
9168            if (mForegroundProcesses.size() > 0) {
9169                if (needSep) pw.println(" ");
9170                needSep = true;
9171                pw.println("  Foreground Processes:");
9172                for (int i=0; i<mForegroundProcesses.size(); i++) {
9173                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
9174                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
9175                }
9176            }
9177
9178            if (mPersistentStartingProcesses.size() > 0) {
9179                if (needSep) pw.println(" ");
9180                needSep = true;
9181                pw.println("  Persisent processes that are starting:");
9182                dumpProcessList(pw, mPersistentStartingProcesses, "    ",
9183                        "Starting Norm", "Restarting PERS", false);
9184            }
9185
9186            if (mStartingProcesses.size() > 0) {
9187                if (needSep) pw.println(" ");
9188                needSep = true;
9189                pw.println("  Processes that are starting:");
9190                dumpProcessList(pw, mStartingProcesses, "    ",
9191                        "Starting Norm", "Starting PERS", false);
9192            }
9193
9194            if (mRemovedProcesses.size() > 0) {
9195                if (needSep) pw.println(" ");
9196                needSep = true;
9197                pw.println("  Processes that are being removed:");
9198                dumpProcessList(pw, mRemovedProcesses, "    ",
9199                        "Removed Norm", "Removed PERS", false);
9200            }
9201
9202            if (mProcessesOnHold.size() > 0) {
9203                if (needSep) pw.println(" ");
9204                needSep = true;
9205                pw.println("  Processes that are on old until the system is ready:");
9206                dumpProcessList(pw, mProcessesOnHold, "    ",
9207                        "OnHold Norm", "OnHold PERS", false);
9208            }
9209
9210            if (mProcessesToGc.size() > 0) {
9211                if (needSep) pw.println(" ");
9212                needSep = true;
9213                pw.println("  Processes that are waiting to GC:");
9214                long now = SystemClock.uptimeMillis();
9215                for (int i=0; i<mProcessesToGc.size(); i++) {
9216                    ProcessRecord proc = mProcessesToGc.get(i);
9217                    pw.print("    Process "); pw.println(proc);
9218                    pw.print("      lowMem="); pw.print(proc.reportLowMemory);
9219                            pw.print(", last gced=");
9220                            pw.print(now-proc.lastRequestedGc);
9221                            pw.print(" ms ago, last lowMem=");
9222                            pw.print(now-proc.lastLowMemory);
9223                            pw.println(" ms ago");
9224
9225                }
9226            }
9227
9228            if (mProcessCrashTimes.getMap().size() > 0) {
9229                if (needSep) pw.println(" ");
9230                needSep = true;
9231                pw.println("  Time since processes crashed:");
9232                long now = SystemClock.uptimeMillis();
9233                for (Map.Entry<String, SparseArray<Long>> procs
9234                        : mProcessCrashTimes.getMap().entrySet()) {
9235                    SparseArray<Long> uids = procs.getValue();
9236                    final int N = uids.size();
9237                    for (int i=0; i<N; i++) {
9238                        pw.print("    Process "); pw.print(procs.getKey());
9239                                pw.print(" uid "); pw.print(uids.keyAt(i));
9240                                pw.print(": last crashed ");
9241                                pw.print((now-uids.valueAt(i)));
9242                                pw.println(" ms ago");
9243                    }
9244                }
9245            }
9246
9247            if (mBadProcesses.getMap().size() > 0) {
9248                if (needSep) pw.println(" ");
9249                needSep = true;
9250                pw.println("  Bad processes:");
9251                for (Map.Entry<String, SparseArray<Long>> procs
9252                        : mBadProcesses.getMap().entrySet()) {
9253                    SparseArray<Long> uids = procs.getValue();
9254                    final int N = uids.size();
9255                    for (int i=0; i<N; i++) {
9256                        pw.print("    Bad process "); pw.print(procs.getKey());
9257                                pw.print(" uid "); pw.print(uids.keyAt(i));
9258                                pw.print(": crashed at time ");
9259                                pw.println(uids.valueAt(i));
9260                    }
9261                }
9262            }
9263
9264            pw.println(" ");
9265            pw.println("  Total persistent processes: " + numPers);
9266            pw.println("  mHomeProcess: " + mHomeProcess);
9267            pw.println("  mConfiguration: " + mConfiguration);
9268            pw.println("  mStartRunning=" + mStartRunning
9269                    + " mSystemReady=" + mSystemReady
9270                    + " mBooting=" + mBooting
9271                    + " mBooted=" + mBooted
9272                    + " mFactoryTest=" + mFactoryTest);
9273            pw.println("  mSleeping=" + mSleeping + " mShuttingDown=" + mShuttingDown);
9274            pw.println("  mGoingToSleep=" + mGoingToSleep);
9275            pw.println("  mLaunchingActivity=" + mLaunchingActivity);
9276            pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
9277                    + " mDebugTransient=" + mDebugTransient
9278                    + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
9279            pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
9280                    + " mController=" + mController);
9281        }
9282    }
9283
9284    /**
9285     * There are three ways to call this:
9286     *  - no service specified: dump all the services
9287     *  - a flattened component name that matched an existing service was specified as the
9288     *    first arg: dump that one service
9289     *  - the first arg isn't the flattened component name of an existing service:
9290     *    dump all services whose component contains the first arg as a substring
9291     */
9292    protected void dumpService(FileDescriptor fd, PrintWriter pw, String[] args) {
9293        String[] newArgs;
9294        String componentNameString;
9295        ServiceRecord r;
9296        if (args.length == 1) {
9297            componentNameString = null;
9298            newArgs = EMPTY_STRING_ARRAY;
9299            r = null;
9300        } else {
9301            componentNameString = args[1];
9302            ComponentName componentName = ComponentName.unflattenFromString(componentNameString);
9303            r = componentName != null ? mServices.get(componentName) : null;
9304            newArgs = new String[args.length - 2];
9305            if (args.length > 2) System.arraycopy(args, 2, newArgs, 0, args.length - 2);
9306        }
9307
9308        if (r != null) {
9309            dumpService(fd, pw, r, newArgs);
9310        } else {
9311            for (ServiceRecord r1 : mServices.values()) {
9312                if (componentNameString == null
9313                        || r1.name.flattenToString().contains(componentNameString)) {
9314                    dumpService(fd, pw, r1, newArgs);
9315                }
9316            }
9317        }
9318    }
9319
9320    /**
9321     * Invokes IApplicationThread.dumpService() on the thread of the specified service if
9322     * there is a thread associated with the service.
9323     */
9324    private void dumpService(FileDescriptor fd, PrintWriter pw, ServiceRecord r, String[] args) {
9325        pw.println("  Service " + r.name.flattenToString());
9326        if (r.app != null && r.app.thread != null) {
9327            try {
9328                // flush anything that is already in the PrintWriter since the thread is going
9329                // to write to the file descriptor directly
9330                pw.flush();
9331                r.app.thread.dumpService(fd, r, args);
9332                pw.print("\n");
9333            } catch (RemoteException e) {
9334                pw.println("got a RemoteException while dumping the service");
9335            }
9336        }
9337    }
9338
9339    void dumpBroadcasts(PrintWriter pw) {
9340        synchronized (this) {
9341            if (checkCallingPermission(android.Manifest.permission.DUMP)
9342                    != PackageManager.PERMISSION_GRANTED) {
9343                pw.println("Permission Denial: can't dump ActivityManager from from pid="
9344                        + Binder.getCallingPid()
9345                        + ", uid=" + Binder.getCallingUid()
9346                        + " without permission "
9347                        + android.Manifest.permission.DUMP);
9348                return;
9349            }
9350            pw.println("Broadcasts in Current Activity Manager State:");
9351
9352            if (mRegisteredReceivers.size() > 0) {
9353                pw.println(" ");
9354                pw.println("  Registered Receivers:");
9355                Iterator it = mRegisteredReceivers.values().iterator();
9356                while (it.hasNext()) {
9357                    ReceiverList r = (ReceiverList)it.next();
9358                    pw.print("  * "); pw.println(r);
9359                    r.dump(pw, "    ");
9360                }
9361            }
9362
9363            pw.println(" ");
9364            pw.println("Receiver Resolver Table:");
9365            mReceiverResolver.dump(pw, "  ");
9366
9367            if (mParallelBroadcasts.size() > 0 || mOrderedBroadcasts.size() > 0
9368                    || mPendingBroadcast != null) {
9369                if (mParallelBroadcasts.size() > 0) {
9370                    pw.println(" ");
9371                    pw.println("  Active broadcasts:");
9372                }
9373                for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
9374                    pw.println("  Broadcast #" + i + ":");
9375                    mParallelBroadcasts.get(i).dump(pw, "    ");
9376                }
9377                if (mOrderedBroadcasts.size() > 0) {
9378                    pw.println(" ");
9379                    pw.println("  Active serialized broadcasts:");
9380                }
9381                for (int i=mOrderedBroadcasts.size()-1; i>=0; i--) {
9382                    pw.println("  Serialized Broadcast #" + i + ":");
9383                    mOrderedBroadcasts.get(i).dump(pw, "    ");
9384                }
9385                pw.println(" ");
9386                pw.println("  Pending broadcast:");
9387                if (mPendingBroadcast != null) {
9388                    mPendingBroadcast.dump(pw, "    ");
9389                } else {
9390                    pw.println("    (null)");
9391                }
9392            }
9393
9394            pw.println(" ");
9395            pw.println("  mBroadcastsScheduled=" + mBroadcastsScheduled);
9396            if (mStickyBroadcasts != null) {
9397                pw.println(" ");
9398                pw.println("  Sticky broadcasts:");
9399                StringBuilder sb = new StringBuilder(128);
9400                for (Map.Entry<String, ArrayList<Intent>> ent
9401                        : mStickyBroadcasts.entrySet()) {
9402                    pw.print("  * Sticky action "); pw.print(ent.getKey());
9403                            pw.println(":");
9404                    ArrayList<Intent> intents = ent.getValue();
9405                    final int N = intents.size();
9406                    for (int i=0; i<N; i++) {
9407                        sb.setLength(0);
9408                        sb.append("    Intent: ");
9409                        intents.get(i).toShortString(sb, true, false);
9410                        pw.println(sb.toString());
9411                        Bundle bundle = intents.get(i).getExtras();
9412                        if (bundle != null) {
9413                            pw.print("      ");
9414                            pw.println(bundle.toString());
9415                        }
9416                    }
9417                }
9418            }
9419
9420            pw.println(" ");
9421            pw.println("  mHandler:");
9422            mHandler.dump(new PrintWriterPrinter(pw), "    ");
9423        }
9424    }
9425
9426    void dumpServices(PrintWriter pw) {
9427        synchronized (this) {
9428            if (checkCallingPermission(android.Manifest.permission.DUMP)
9429                    != PackageManager.PERMISSION_GRANTED) {
9430                pw.println("Permission Denial: can't dump ActivityManager from from pid="
9431                        + Binder.getCallingPid()
9432                        + ", uid=" + Binder.getCallingUid()
9433                        + " without permission "
9434                        + android.Manifest.permission.DUMP);
9435                return;
9436            }
9437            pw.println("Services in Current Activity Manager State:");
9438
9439            boolean needSep = false;
9440
9441            if (mServices.size() > 0) {
9442                pw.println("  Active services:");
9443                Iterator<ServiceRecord> it = mServices.values().iterator();
9444                while (it.hasNext()) {
9445                    ServiceRecord r = it.next();
9446                    pw.print("  * "); pw.println(r);
9447                    r.dump(pw, "    ");
9448                }
9449                needSep = true;
9450            }
9451
9452            if (mPendingServices.size() > 0) {
9453                if (needSep) pw.println(" ");
9454                pw.println("  Pending services:");
9455                for (int i=0; i<mPendingServices.size(); i++) {
9456                    ServiceRecord r = mPendingServices.get(i);
9457                    pw.print("  * Pending "); pw.println(r);
9458                    r.dump(pw, "    ");
9459                }
9460                needSep = true;
9461            }
9462
9463            if (mRestartingServices.size() > 0) {
9464                if (needSep) pw.println(" ");
9465                pw.println("  Restarting services:");
9466                for (int i=0; i<mRestartingServices.size(); i++) {
9467                    ServiceRecord r = mRestartingServices.get(i);
9468                    pw.print("  * Restarting "); pw.println(r);
9469                    r.dump(pw, "    ");
9470                }
9471                needSep = true;
9472            }
9473
9474            if (mStoppingServices.size() > 0) {
9475                if (needSep) pw.println(" ");
9476                pw.println("  Stopping services:");
9477                for (int i=0; i<mStoppingServices.size(); i++) {
9478                    ServiceRecord r = mStoppingServices.get(i);
9479                    pw.print("  * Stopping "); pw.println(r);
9480                    r.dump(pw, "    ");
9481                }
9482                needSep = true;
9483            }
9484
9485            if (mServiceConnections.size() > 0) {
9486                if (needSep) pw.println(" ");
9487                pw.println("  Connection bindings to services:");
9488                Iterator<ConnectionRecord> it
9489                        = mServiceConnections.values().iterator();
9490                while (it.hasNext()) {
9491                    ConnectionRecord r = it.next();
9492                    pw.print("  * "); pw.println(r);
9493                    r.dump(pw, "    ");
9494                }
9495            }
9496        }
9497    }
9498
9499    void dumpProviders(PrintWriter pw) {
9500        synchronized (this) {
9501            if (checkCallingPermission(android.Manifest.permission.DUMP)
9502                    != PackageManager.PERMISSION_GRANTED) {
9503                pw.println("Permission Denial: can't dump ActivityManager from from pid="
9504                        + Binder.getCallingPid()
9505                        + ", uid=" + Binder.getCallingUid()
9506                        + " without permission "
9507                        + android.Manifest.permission.DUMP);
9508                return;
9509            }
9510
9511            pw.println("Content Providers in Current Activity Manager State:");
9512
9513            boolean needSep = false;
9514
9515            if (mProvidersByClass.size() > 0) {
9516                if (needSep) pw.println(" ");
9517                pw.println("  Published content providers (by class):");
9518                Iterator it = mProvidersByClass.entrySet().iterator();
9519                while (it.hasNext()) {
9520                    Map.Entry e = (Map.Entry)it.next();
9521                    ContentProviderRecord r = (ContentProviderRecord)e.getValue();
9522                    pw.print("  * "); pw.println(r);
9523                    r.dump(pw, "    ");
9524                }
9525                needSep = true;
9526            }
9527
9528            if (mProvidersByName.size() > 0) {
9529                pw.println(" ");
9530                pw.println("  Authority to provider mappings:");
9531                Iterator it = mProvidersByName.entrySet().iterator();
9532                while (it.hasNext()) {
9533                    Map.Entry e = (Map.Entry)it.next();
9534                    ContentProviderRecord r = (ContentProviderRecord)e.getValue();
9535                    pw.print("  "); pw.print(e.getKey()); pw.print(": ");
9536                            pw.println(r);
9537                }
9538                needSep = true;
9539            }
9540
9541            if (mLaunchingProviders.size() > 0) {
9542                if (needSep) pw.println(" ");
9543                pw.println("  Launching content providers:");
9544                for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
9545                    pw.print("  Launching #"); pw.print(i); pw.print(": ");
9546                            pw.println(mLaunchingProviders.get(i));
9547                }
9548                needSep = true;
9549            }
9550
9551            if (mGrantedUriPermissions.size() > 0) {
9552                pw.println();
9553                pw.println("Granted Uri Permissions:");
9554                for (int i=0; i<mGrantedUriPermissions.size(); i++) {
9555                    int uid = mGrantedUriPermissions.keyAt(i);
9556                    HashMap<Uri, UriPermission> perms
9557                            = mGrantedUriPermissions.valueAt(i);
9558                    pw.print("  * UID "); pw.print(uid);
9559                            pw.println(" holds:");
9560                    for (UriPermission perm : perms.values()) {
9561                        pw.print("    "); pw.println(perm);
9562                        perm.dump(pw, "      ");
9563                    }
9564                }
9565            }
9566        }
9567    }
9568
9569    void dumpSenders(PrintWriter pw) {
9570        synchronized (this) {
9571            if (checkCallingPermission(android.Manifest.permission.DUMP)
9572                    != PackageManager.PERMISSION_GRANTED) {
9573                pw.println("Permission Denial: can't dump ActivityManager from from pid="
9574                        + Binder.getCallingPid()
9575                        + ", uid=" + Binder.getCallingUid()
9576                        + " without permission "
9577                        + android.Manifest.permission.DUMP);
9578                return;
9579            }
9580
9581            pw.println("Pending Intents in Current Activity Manager State:");
9582
9583            if (this.mIntentSenderRecords.size() > 0) {
9584                Iterator<WeakReference<PendingIntentRecord>> it
9585                        = mIntentSenderRecords.values().iterator();
9586                while (it.hasNext()) {
9587                    WeakReference<PendingIntentRecord> ref = it.next();
9588                    PendingIntentRecord rec = ref != null ? ref.get(): null;
9589                    if (rec != null) {
9590                        pw.print("  * "); pw.println(rec);
9591                        rec.dump(pw, "    ");
9592                    } else {
9593                        pw.print("  * "); pw.print(ref);
9594                    }
9595                }
9596            }
9597        }
9598    }
9599
9600    private static final void dumpHistoryList(PrintWriter pw, List list,
9601            String prefix, String label, boolean complete) {
9602        TaskRecord lastTask = null;
9603        for (int i=list.size()-1; i>=0; i--) {
9604            HistoryRecord r = (HistoryRecord)list.get(i);
9605            final boolean full = complete || !r.inHistory;
9606            if (lastTask != r.task) {
9607                lastTask = r.task;
9608                pw.print(prefix);
9609                pw.print(full ? "* " : "  ");
9610                pw.println(lastTask);
9611                if (full) {
9612                    lastTask.dump(pw, prefix + "  ");
9613                }
9614            }
9615            pw.print(prefix); pw.print(full ? "  * " : "    "); pw.print(label);
9616            pw.print(" #"); pw.print(i); pw.print(": ");
9617            pw.println(r);
9618            if (full) {
9619                r.dump(pw, prefix + "      ");
9620            }
9621        }
9622    }
9623
9624    private static final int dumpProcessList(PrintWriter pw, List list,
9625            String prefix, String normalLabel, String persistentLabel,
9626            boolean inclOomAdj) {
9627        int numPers = 0;
9628        for (int i=list.size()-1; i>=0; i--) {
9629            ProcessRecord r = (ProcessRecord)list.get(i);
9630            if (false) {
9631                pw.println(prefix + (r.persistent ? persistentLabel : normalLabel)
9632                      + " #" + i + ":");
9633                r.dump(pw, prefix + "  ");
9634            } else if (inclOomAdj) {
9635                pw.println(String.format("%s%s #%2d: adj=%4d/%d %s (%s)",
9636                        prefix, (r.persistent ? persistentLabel : normalLabel),
9637                        i, r.setAdj, r.setSchedGroup, r.toString(), r.adjType));
9638                if (r.adjSource != null || r.adjTarget != null) {
9639                    pw.println(prefix + "          " + r.adjTarget
9640                            + " used by " + r.adjSource);
9641                }
9642            } else {
9643                pw.println(String.format("%s%s #%2d: %s",
9644                        prefix, (r.persistent ? persistentLabel : normalLabel),
9645                        i, r.toString()));
9646            }
9647            if (r.persistent) {
9648                numPers++;
9649            }
9650        }
9651        return numPers;
9652    }
9653
9654    private static final void dumpApplicationMemoryUsage(FileDescriptor fd,
9655            PrintWriter pw, List list, String prefix, String[] args) {
9656        final boolean isCheckinRequest = scanArgs(args, "--checkin");
9657        long uptime = SystemClock.uptimeMillis();
9658        long realtime = SystemClock.elapsedRealtime();
9659
9660        if (isCheckinRequest) {
9661            // short checkin version
9662            pw.println(uptime + "," + realtime);
9663            pw.flush();
9664        } else {
9665            pw.println("Applications Memory Usage (kB):");
9666            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
9667        }
9668        for (int i = list.size() - 1 ; i >= 0 ; i--) {
9669            ProcessRecord r = (ProcessRecord)list.get(i);
9670            if (r.thread != null) {
9671                if (!isCheckinRequest) {
9672                    pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
9673                    pw.flush();
9674                }
9675                try {
9676                    r.thread.asBinder().dump(fd, args);
9677                } catch (RemoteException e) {
9678                    if (!isCheckinRequest) {
9679                        pw.println("Got RemoteException!");
9680                        pw.flush();
9681                    }
9682                }
9683            }
9684        }
9685    }
9686
9687    /**
9688     * Searches array of arguments for the specified string
9689     * @param args array of argument strings
9690     * @param value value to search for
9691     * @return true if the value is contained in the array
9692     */
9693    private static boolean scanArgs(String[] args, String value) {
9694        if (args != null) {
9695            for (String arg : args) {
9696                if (value.equals(arg)) {
9697                    return true;
9698                }
9699            }
9700        }
9701        return false;
9702    }
9703
9704    private final int indexOfTokenLocked(IBinder token) {
9705        int count = mHistory.size();
9706
9707        // convert the token to an entry in the history.
9708        HistoryRecord r = null;
9709        int index = -1;
9710        for (int i=count-1; i>=0; i--) {
9711            Object o = mHistory.get(i);
9712            if (o == token) {
9713                r = (HistoryRecord)o;
9714                index = i;
9715                break;
9716            }
9717        }
9718
9719        return index;
9720    }
9721
9722    private final void killServicesLocked(ProcessRecord app,
9723            boolean allowRestart) {
9724        // Report disconnected services.
9725        if (false) {
9726            // XXX we are letting the client link to the service for
9727            // death notifications.
9728            if (app.services.size() > 0) {
9729                Iterator it = app.services.iterator();
9730                while (it.hasNext()) {
9731                    ServiceRecord r = (ServiceRecord)it.next();
9732                    if (r.connections.size() > 0) {
9733                        Iterator<ConnectionRecord> jt
9734                                = r.connections.values().iterator();
9735                        while (jt.hasNext()) {
9736                            ConnectionRecord c = jt.next();
9737                            if (c.binding.client != app) {
9738                                try {
9739                                    //c.conn.connected(r.className, null);
9740                                } catch (Exception e) {
9741                                    // todo: this should be asynchronous!
9742                                    Log.w(TAG, "Exception thrown disconnected servce "
9743                                          + r.shortName
9744                                          + " from app " + app.processName, e);
9745                                }
9746                            }
9747                        }
9748                    }
9749                }
9750            }
9751        }
9752
9753        // Clean up any connections this application has to other services.
9754        if (app.connections.size() > 0) {
9755            Iterator<ConnectionRecord> it = app.connections.iterator();
9756            while (it.hasNext()) {
9757                ConnectionRecord r = it.next();
9758                removeConnectionLocked(r, app, null);
9759            }
9760        }
9761        app.connections.clear();
9762
9763        if (app.services.size() != 0) {
9764            // Any services running in the application need to be placed
9765            // back in the pending list.
9766            Iterator it = app.services.iterator();
9767            while (it.hasNext()) {
9768                ServiceRecord sr = (ServiceRecord)it.next();
9769                synchronized (sr.stats.getBatteryStats()) {
9770                    sr.stats.stopLaunchedLocked();
9771                }
9772                sr.app = null;
9773                sr.executeNesting = 0;
9774                mStoppingServices.remove(sr);
9775
9776                boolean hasClients = sr.bindings.size() > 0;
9777                if (hasClients) {
9778                    Iterator<IntentBindRecord> bindings
9779                            = sr.bindings.values().iterator();
9780                    while (bindings.hasNext()) {
9781                        IntentBindRecord b = bindings.next();
9782                        if (DEBUG_SERVICE) Log.v(TAG, "Killing binding " + b
9783                                + ": shouldUnbind=" + b.hasBound);
9784                        b.binder = null;
9785                        b.requested = b.received = b.hasBound = false;
9786                    }
9787                }
9788
9789                if (sr.crashCount >= 2) {
9790                    Log.w(TAG, "Service crashed " + sr.crashCount
9791                            + " times, stopping: " + sr);
9792                    EventLog.writeEvent(LOG_AM_SERVICE_CRASHED_TOO_MUCH,
9793                            sr.crashCount, sr.shortName, app.pid);
9794                    bringDownServiceLocked(sr, true);
9795                } else if (!allowRestart) {
9796                    bringDownServiceLocked(sr, true);
9797                } else {
9798                    boolean canceled = scheduleServiceRestartLocked(sr, true);
9799
9800                    // Should the service remain running?  Note that in the
9801                    // extreme case of so many attempts to deliver a command
9802                    // that it failed, that we also will stop it here.
9803                    if (sr.startRequested && (sr.stopIfKilled || canceled)) {
9804                        if (sr.pendingStarts.size() == 0) {
9805                            sr.startRequested = false;
9806                            if (!hasClients) {
9807                                // Whoops, no reason to restart!
9808                                bringDownServiceLocked(sr, true);
9809                            }
9810                        }
9811                    }
9812                }
9813            }
9814
9815            if (!allowRestart) {
9816                app.services.clear();
9817            }
9818        }
9819
9820        // Make sure we have no more records on the stopping list.
9821        int i = mStoppingServices.size();
9822        while (i > 0) {
9823            i--;
9824            ServiceRecord sr = mStoppingServices.get(i);
9825            if (sr.app == app) {
9826                mStoppingServices.remove(i);
9827            }
9828        }
9829
9830        app.executingServices.clear();
9831    }
9832
9833    private final void removeDyingProviderLocked(ProcessRecord proc,
9834            ContentProviderRecord cpr) {
9835        synchronized (cpr) {
9836            cpr.launchingApp = null;
9837            cpr.notifyAll();
9838        }
9839
9840        mProvidersByClass.remove(cpr.info.name);
9841        String names[] = cpr.info.authority.split(";");
9842        for (int j = 0; j < names.length; j++) {
9843            mProvidersByName.remove(names[j]);
9844        }
9845
9846        Iterator<ProcessRecord> cit = cpr.clients.iterator();
9847        while (cit.hasNext()) {
9848            ProcessRecord capp = cit.next();
9849            if (!capp.persistent && capp.thread != null
9850                    && capp.pid != 0
9851                    && capp.pid != MY_PID) {
9852                Log.i(TAG, "Killing app " + capp.processName
9853                        + " (pid " + capp.pid
9854                        + ") because provider " + cpr.info.name
9855                        + " is in dying process " + proc.processName);
9856                Process.killProcess(capp.pid);
9857            }
9858        }
9859
9860        mLaunchingProviders.remove(cpr);
9861    }
9862
9863    /**
9864     * Main code for cleaning up a process when it has gone away.  This is
9865     * called both as a result of the process dying, or directly when stopping
9866     * a process when running in single process mode.
9867     */
9868    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
9869            boolean restarting, int index) {
9870        if (index >= 0) {
9871            mLRUProcesses.remove(index);
9872        }
9873
9874        mProcessesToGc.remove(app);
9875
9876        // Dismiss any open dialogs.
9877        if (app.crashDialog != null) {
9878            app.crashDialog.dismiss();
9879            app.crashDialog = null;
9880        }
9881        if (app.anrDialog != null) {
9882            app.anrDialog.dismiss();
9883            app.anrDialog = null;
9884        }
9885        if (app.waitDialog != null) {
9886            app.waitDialog.dismiss();
9887            app.waitDialog = null;
9888        }
9889
9890        app.crashing = false;
9891        app.notResponding = false;
9892
9893        app.resetPackageList();
9894        app.thread = null;
9895        app.forcingToForeground = null;
9896        app.foregroundServices = false;
9897
9898        killServicesLocked(app, true);
9899
9900        boolean restart = false;
9901
9902        int NL = mLaunchingProviders.size();
9903
9904        // Remove published content providers.
9905        if (!app.pubProviders.isEmpty()) {
9906            Iterator it = app.pubProviders.values().iterator();
9907            while (it.hasNext()) {
9908                ContentProviderRecord cpr = (ContentProviderRecord)it.next();
9909                cpr.provider = null;
9910                cpr.app = null;
9911
9912                // See if someone is waiting for this provider...  in which
9913                // case we don't remove it, but just let it restart.
9914                int i = 0;
9915                if (!app.bad) {
9916                    for (; i<NL; i++) {
9917                        if (mLaunchingProviders.get(i) == cpr) {
9918                            restart = true;
9919                            break;
9920                        }
9921                    }
9922                } else {
9923                    i = NL;
9924                }
9925
9926                if (i >= NL) {
9927                    removeDyingProviderLocked(app, cpr);
9928                    NL = mLaunchingProviders.size();
9929                }
9930            }
9931            app.pubProviders.clear();
9932        }
9933
9934        // Look through the content providers we are waiting to have launched,
9935        // and if any run in this process then either schedule a restart of
9936        // the process or kill the client waiting for it if this process has
9937        // gone bad.
9938        for (int i=0; i<NL; i++) {
9939            ContentProviderRecord cpr = (ContentProviderRecord)
9940                    mLaunchingProviders.get(i);
9941            if (cpr.launchingApp == app) {
9942                if (!app.bad) {
9943                    restart = true;
9944                } else {
9945                    removeDyingProviderLocked(app, cpr);
9946                    NL = mLaunchingProviders.size();
9947                }
9948            }
9949        }
9950
9951        // Unregister from connected content providers.
9952        if (!app.conProviders.isEmpty()) {
9953            Iterator it = app.conProviders.keySet().iterator();
9954            while (it.hasNext()) {
9955                ContentProviderRecord cpr = (ContentProviderRecord)it.next();
9956                cpr.clients.remove(app);
9957            }
9958            app.conProviders.clear();
9959        }
9960
9961        // At this point there may be remaining entries in mLaunchingProviders
9962        // where we were the only one waiting, so they are no longer of use.
9963        // Look for these and clean up if found.
9964        // XXX Commented out for now.  Trying to figure out a way to reproduce
9965        // the actual situation to identify what is actually going on.
9966        if (false) {
9967            for (int i=0; i<NL; i++) {
9968                ContentProviderRecord cpr = (ContentProviderRecord)
9969                        mLaunchingProviders.get(i);
9970                if (cpr.clients.size() <= 0 && cpr.externals <= 0) {
9971                    synchronized (cpr) {
9972                        cpr.launchingApp = null;
9973                        cpr.notifyAll();
9974                    }
9975                }
9976            }
9977        }
9978
9979        skipCurrentReceiverLocked(app);
9980
9981        // Unregister any receivers.
9982        if (app.receivers.size() > 0) {
9983            Iterator<ReceiverList> it = app.receivers.iterator();
9984            while (it.hasNext()) {
9985                removeReceiverLocked(it.next());
9986            }
9987            app.receivers.clear();
9988        }
9989
9990        // If the app is undergoing backup, tell the backup manager about it
9991        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
9992            if (DEBUG_BACKUP) Log.d(TAG, "App " + mBackupTarget.appInfo + " died during backup");
9993            try {
9994                IBackupManager bm = IBackupManager.Stub.asInterface(
9995                        ServiceManager.getService(Context.BACKUP_SERVICE));
9996                bm.agentDisconnected(app.info.packageName);
9997            } catch (RemoteException e) {
9998                // can't happen; backup manager is local
9999            }
10000        }
10001
10002        // If the caller is restarting this app, then leave it in its
10003        // current lists and let the caller take care of it.
10004        if (restarting) {
10005            return;
10006        }
10007
10008        if (!app.persistent) {
10009            if (DEBUG_PROCESSES) Log.v(TAG,
10010                    "Removing non-persistent process during cleanup: " + app);
10011            mProcessNames.remove(app.processName, app.info.uid);
10012        } else if (!app.removed) {
10013            // This app is persistent, so we need to keep its record around.
10014            // If it is not already on the pending app list, add it there
10015            // and start a new process for it.
10016            app.thread = null;
10017            app.forcingToForeground = null;
10018            app.foregroundServices = false;
10019            if (mPersistentStartingProcesses.indexOf(app) < 0) {
10020                mPersistentStartingProcesses.add(app);
10021                restart = true;
10022            }
10023        }
10024        mProcessesOnHold.remove(app);
10025
10026        if (app == mHomeProcess) {
10027            mHomeProcess = null;
10028        }
10029
10030        if (restart) {
10031            // We have components that still need to be running in the
10032            // process, so re-launch it.
10033            mProcessNames.put(app.processName, app.info.uid, app);
10034            startProcessLocked(app, "restart", app.processName);
10035        } else if (app.pid > 0 && app.pid != MY_PID) {
10036            // Goodbye!
10037            synchronized (mPidsSelfLocked) {
10038                mPidsSelfLocked.remove(app.pid);
10039                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
10040            }
10041            app.setPid(0);
10042        }
10043    }
10044
10045    // =========================================================
10046    // SERVICES
10047    // =========================================================
10048
10049    ActivityManager.RunningServiceInfo makeRunningServiceInfoLocked(ServiceRecord r) {
10050        ActivityManager.RunningServiceInfo info =
10051            new ActivityManager.RunningServiceInfo();
10052        info.service = r.name;
10053        if (r.app != null) {
10054            info.pid = r.app.pid;
10055        }
10056        info.uid = r.appInfo.uid;
10057        info.process = r.processName;
10058        info.foreground = r.isForeground;
10059        info.activeSince = r.createTime;
10060        info.started = r.startRequested;
10061        info.clientCount = r.connections.size();
10062        info.crashCount = r.crashCount;
10063        info.lastActivityTime = r.lastActivity;
10064        if (r.isForeground) {
10065            info.flags |= ActivityManager.RunningServiceInfo.FLAG_FOREGROUND;
10066        }
10067        if (r.startRequested) {
10068            info.flags |= ActivityManager.RunningServiceInfo.FLAG_STARTED;
10069        }
10070        if (r.app != null && r.app.pid == Process.myPid()) {
10071            info.flags |= ActivityManager.RunningServiceInfo.FLAG_SYSTEM_PROCESS;
10072        }
10073        if (r.app != null && r.app.persistent) {
10074            info.flags |= ActivityManager.RunningServiceInfo.FLAG_PERSISTENT_PROCESS;
10075        }
10076        for (ConnectionRecord conn : r.connections.values()) {
10077            if (conn.clientLabel != 0) {
10078                info.clientPackage = conn.binding.client.info.packageName;
10079                info.clientLabel = conn.clientLabel;
10080                break;
10081            }
10082        }
10083        return info;
10084    }
10085
10086    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
10087            int flags) {
10088        synchronized (this) {
10089            ArrayList<ActivityManager.RunningServiceInfo> res
10090                    = new ArrayList<ActivityManager.RunningServiceInfo>();
10091
10092            if (mServices.size() > 0) {
10093                Iterator<ServiceRecord> it = mServices.values().iterator();
10094                while (it.hasNext() && res.size() < maxNum) {
10095                    res.add(makeRunningServiceInfoLocked(it.next()));
10096                }
10097            }
10098
10099            for (int i=0; i<mRestartingServices.size() && res.size() < maxNum; i++) {
10100                ServiceRecord r = mRestartingServices.get(i);
10101                ActivityManager.RunningServiceInfo info =
10102                        makeRunningServiceInfoLocked(r);
10103                info.restarting = r.nextRestartTime;
10104                res.add(info);
10105            }
10106
10107            return res;
10108        }
10109    }
10110
10111    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
10112        synchronized (this) {
10113            ServiceRecord r = mServices.get(name);
10114            if (r != null) {
10115                for (ConnectionRecord conn : r.connections.values()) {
10116                    if (conn.clientIntent != null) {
10117                        return conn.clientIntent;
10118                    }
10119                }
10120            }
10121        }
10122        return null;
10123    }
10124
10125    private final ServiceRecord findServiceLocked(ComponentName name,
10126            IBinder token) {
10127        ServiceRecord r = mServices.get(name);
10128        return r == token ? r : null;
10129    }
10130
10131    private final class ServiceLookupResult {
10132        final ServiceRecord record;
10133        final String permission;
10134
10135        ServiceLookupResult(ServiceRecord _record, String _permission) {
10136            record = _record;
10137            permission = _permission;
10138        }
10139    };
10140
10141    private ServiceLookupResult findServiceLocked(Intent service,
10142            String resolvedType) {
10143        ServiceRecord r = null;
10144        if (service.getComponent() != null) {
10145            r = mServices.get(service.getComponent());
10146        }
10147        if (r == null) {
10148            Intent.FilterComparison filter = new Intent.FilterComparison(service);
10149            r = mServicesByIntent.get(filter);
10150        }
10151
10152        if (r == null) {
10153            try {
10154                ResolveInfo rInfo =
10155                    ActivityThread.getPackageManager().resolveService(
10156                            service, resolvedType, 0);
10157                ServiceInfo sInfo =
10158                    rInfo != null ? rInfo.serviceInfo : null;
10159                if (sInfo == null) {
10160                    return null;
10161                }
10162
10163                ComponentName name = new ComponentName(
10164                        sInfo.applicationInfo.packageName, sInfo.name);
10165                r = mServices.get(name);
10166            } catch (RemoteException ex) {
10167                // pm is in same process, this will never happen.
10168            }
10169        }
10170        if (r != null) {
10171            int callingPid = Binder.getCallingPid();
10172            int callingUid = Binder.getCallingUid();
10173            if (checkComponentPermission(r.permission,
10174                    callingPid, callingUid, r.exported ? -1 : r.appInfo.uid)
10175                    != PackageManager.PERMISSION_GRANTED) {
10176                Log.w(TAG, "Permission Denial: Accessing service " + r.name
10177                        + " from pid=" + callingPid
10178                        + ", uid=" + callingUid
10179                        + " requires " + r.permission);
10180                return new ServiceLookupResult(null, r.permission);
10181            }
10182            return new ServiceLookupResult(r, null);
10183        }
10184        return null;
10185    }
10186
10187    private class ServiceRestarter implements Runnable {
10188        private ServiceRecord mService;
10189
10190        void setService(ServiceRecord service) {
10191            mService = service;
10192        }
10193
10194        public void run() {
10195            synchronized(ActivityManagerService.this) {
10196                performServiceRestartLocked(mService);
10197            }
10198        }
10199    }
10200
10201    private ServiceLookupResult retrieveServiceLocked(Intent service,
10202            String resolvedType, int callingPid, int callingUid) {
10203        ServiceRecord r = null;
10204        if (service.getComponent() != null) {
10205            r = mServices.get(service.getComponent());
10206        }
10207        Intent.FilterComparison filter = new Intent.FilterComparison(service);
10208        r = mServicesByIntent.get(filter);
10209        if (r == null) {
10210            try {
10211                ResolveInfo rInfo =
10212                    ActivityThread.getPackageManager().resolveService(
10213                            service, resolvedType, STOCK_PM_FLAGS);
10214                ServiceInfo sInfo =
10215                    rInfo != null ? rInfo.serviceInfo : null;
10216                if (sInfo == null) {
10217                    Log.w(TAG, "Unable to start service " + service +
10218                          ": not found");
10219                    return null;
10220                }
10221
10222                ComponentName name = new ComponentName(
10223                        sInfo.applicationInfo.packageName, sInfo.name);
10224                r = mServices.get(name);
10225                if (r == null) {
10226                    filter = new Intent.FilterComparison(service.cloneFilter());
10227                    ServiceRestarter res = new ServiceRestarter();
10228                    BatteryStatsImpl.Uid.Pkg.Serv ss = null;
10229                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10230                    synchronized (stats) {
10231                        ss = stats.getServiceStatsLocked(
10232                                sInfo.applicationInfo.uid, sInfo.packageName,
10233                                sInfo.name);
10234                    }
10235                    r = new ServiceRecord(ss, name, filter, sInfo, res);
10236                    res.setService(r);
10237                    mServices.put(name, r);
10238                    mServicesByIntent.put(filter, r);
10239
10240                    // Make sure this component isn't in the pending list.
10241                    int N = mPendingServices.size();
10242                    for (int i=0; i<N; i++) {
10243                        ServiceRecord pr = mPendingServices.get(i);
10244                        if (pr.name.equals(name)) {
10245                            mPendingServices.remove(i);
10246                            i--;
10247                            N--;
10248                        }
10249                    }
10250                }
10251            } catch (RemoteException ex) {
10252                // pm is in same process, this will never happen.
10253            }
10254        }
10255        if (r != null) {
10256            if (checkComponentPermission(r.permission,
10257                    callingPid, callingUid, r.exported ? -1 : r.appInfo.uid)
10258                    != PackageManager.PERMISSION_GRANTED) {
10259                Log.w(TAG, "Permission Denial: Accessing service " + r.name
10260                        + " from pid=" + Binder.getCallingPid()
10261                        + ", uid=" + Binder.getCallingUid()
10262                        + " requires " + r.permission);
10263                return new ServiceLookupResult(null, r.permission);
10264            }
10265            return new ServiceLookupResult(r, null);
10266        }
10267        return null;
10268    }
10269
10270    private final void bumpServiceExecutingLocked(ServiceRecord r) {
10271        long now = SystemClock.uptimeMillis();
10272        if (r.executeNesting == 0 && r.app != null) {
10273            if (r.app.executingServices.size() == 0) {
10274                Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
10275                msg.obj = r.app;
10276                mHandler.sendMessageAtTime(msg, now+SERVICE_TIMEOUT);
10277            }
10278            r.app.executingServices.add(r);
10279        }
10280        r.executeNesting++;
10281        r.executingStart = now;
10282    }
10283
10284    private final void sendServiceArgsLocked(ServiceRecord r,
10285            boolean oomAdjusted) {
10286        final int N = r.pendingStarts.size();
10287        if (N == 0) {
10288            return;
10289        }
10290
10291        int i = 0;
10292        while (i < N) {
10293            try {
10294                ServiceRecord.StartItem si = r.pendingStarts.get(i);
10295                if (DEBUG_SERVICE) Log.v(TAG, "Sending arguments to service: "
10296                        + r.name + " " + r.intent + " args=" + si.intent);
10297                if (si.intent == null && N > 1) {
10298                    // If somehow we got a dummy start at the front, then
10299                    // just drop it here.
10300                    i++;
10301                    continue;
10302                }
10303                bumpServiceExecutingLocked(r);
10304                if (!oomAdjusted) {
10305                    oomAdjusted = true;
10306                    updateOomAdjLocked(r.app);
10307                }
10308                int flags = 0;
10309                if (si.deliveryCount > 0) {
10310                    flags |= Service.START_FLAG_RETRY;
10311                }
10312                if (si.doneExecutingCount > 0) {
10313                    flags |= Service.START_FLAG_REDELIVERY;
10314                }
10315                r.app.thread.scheduleServiceArgs(r, si.id, flags, si.intent);
10316                si.deliveredTime = SystemClock.uptimeMillis();
10317                r.deliveredStarts.add(si);
10318                si.deliveryCount++;
10319                i++;
10320            } catch (RemoteException e) {
10321                // Remote process gone...  we'll let the normal cleanup take
10322                // care of this.
10323                break;
10324            } catch (Exception e) {
10325                Log.w(TAG, "Unexpected exception", e);
10326                break;
10327            }
10328        }
10329        if (i == N) {
10330            r.pendingStarts.clear();
10331        } else {
10332            while (i > 0) {
10333                i--;
10334                r.pendingStarts.remove(i);
10335            }
10336        }
10337    }
10338
10339    private final boolean requestServiceBindingLocked(ServiceRecord r,
10340            IntentBindRecord i, boolean rebind) {
10341        if (r.app == null || r.app.thread == null) {
10342            // If service is not currently running, can't yet bind.
10343            return false;
10344        }
10345        if ((!i.requested || rebind) && i.apps.size() > 0) {
10346            try {
10347                bumpServiceExecutingLocked(r);
10348                if (DEBUG_SERVICE) Log.v(TAG, "Connecting binding " + i
10349                        + ": shouldUnbind=" + i.hasBound);
10350                r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind);
10351                if (!rebind) {
10352                    i.requested = true;
10353                }
10354                i.hasBound = true;
10355                i.doRebind = false;
10356            } catch (RemoteException e) {
10357                return false;
10358            }
10359        }
10360        return true;
10361    }
10362
10363    private final void requestServiceBindingsLocked(ServiceRecord r) {
10364        Iterator<IntentBindRecord> bindings = r.bindings.values().iterator();
10365        while (bindings.hasNext()) {
10366            IntentBindRecord i = bindings.next();
10367            if (!requestServiceBindingLocked(r, i, false)) {
10368                break;
10369            }
10370        }
10371    }
10372
10373    private final void realStartServiceLocked(ServiceRecord r,
10374            ProcessRecord app) throws RemoteException {
10375        if (app.thread == null) {
10376            throw new RemoteException();
10377        }
10378
10379        r.app = app;
10380        r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
10381
10382        app.services.add(r);
10383        bumpServiceExecutingLocked(r);
10384        updateLRUListLocked(app, true);
10385
10386        boolean created = false;
10387        try {
10388            if (DEBUG_SERVICE) Log.v(TAG, "Scheduling start service: "
10389                    + r.name + " " + r.intent);
10390            mStringBuilder.setLength(0);
10391            r.intent.getIntent().toShortString(mStringBuilder, false, true);
10392            EventLog.writeEvent(LOG_AM_CREATE_SERVICE,
10393                    System.identityHashCode(r), r.shortName,
10394                    mStringBuilder.toString(), r.app.pid);
10395            synchronized (r.stats.getBatteryStats()) {
10396                r.stats.startLaunchedLocked();
10397            }
10398            ensurePackageDexOpt(r.serviceInfo.packageName);
10399            app.thread.scheduleCreateService(r, r.serviceInfo);
10400            r.postNotification();
10401            created = true;
10402        } finally {
10403            if (!created) {
10404                app.services.remove(r);
10405                scheduleServiceRestartLocked(r, false);
10406            }
10407        }
10408
10409        requestServiceBindingsLocked(r);
10410
10411        // If the service is in the started state, and there are no
10412        // pending arguments, then fake up one so its onStartCommand() will
10413        // be called.
10414        if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
10415            r.lastStartId++;
10416            if (r.lastStartId < 1) {
10417                r.lastStartId = 1;
10418            }
10419            r.pendingStarts.add(new ServiceRecord.StartItem(r.lastStartId, null));
10420        }
10421
10422        sendServiceArgsLocked(r, true);
10423    }
10424
10425    private final boolean scheduleServiceRestartLocked(ServiceRecord r,
10426            boolean allowCancel) {
10427        boolean canceled = false;
10428
10429        final long now = SystemClock.uptimeMillis();
10430        long minDuration = SERVICE_RESTART_DURATION;
10431        long resetTime = SERVICE_RESET_RUN_DURATION;
10432
10433        // Any delivered but not yet finished starts should be put back
10434        // on the pending list.
10435        final int N = r.deliveredStarts.size();
10436        if (N > 0) {
10437            for (int i=N-1; i>=0; i--) {
10438                ServiceRecord.StartItem si = r.deliveredStarts.get(i);
10439                if (si.intent == null) {
10440                    // We'll generate this again if needed.
10441                } else if (!allowCancel || (si.deliveryCount < ServiceRecord.MAX_DELIVERY_COUNT
10442                        && si.doneExecutingCount < ServiceRecord.MAX_DONE_EXECUTING_COUNT)) {
10443                    r.pendingStarts.add(0, si);
10444                    long dur = SystemClock.uptimeMillis() - si.deliveredTime;
10445                    dur *= 2;
10446                    if (minDuration < dur) minDuration = dur;
10447                    if (resetTime < dur) resetTime = dur;
10448                } else {
10449                    Log.w(TAG, "Canceling start item " + si.intent + " in service "
10450                            + r.name);
10451                    canceled = true;
10452                }
10453            }
10454            r.deliveredStarts.clear();
10455        }
10456
10457        r.totalRestartCount++;
10458        if (r.restartDelay == 0) {
10459            r.restartCount++;
10460            r.restartDelay = minDuration;
10461        } else {
10462            // If it has been a "reasonably long time" since the service
10463            // was started, then reset our restart duration back to
10464            // the beginning, so we don't infinitely increase the duration
10465            // on a service that just occasionally gets killed (which is
10466            // a normal case, due to process being killed to reclaim memory).
10467            if (now > (r.restartTime+resetTime)) {
10468                r.restartCount = 1;
10469                r.restartDelay = minDuration;
10470            } else {
10471                r.restartDelay *= SERVICE_RESTART_DURATION_FACTOR;
10472                if (r.restartDelay < minDuration) {
10473                    r.restartDelay = minDuration;
10474                }
10475            }
10476        }
10477
10478        r.nextRestartTime = now + r.restartDelay;
10479
10480        // Make sure that we don't end up restarting a bunch of services
10481        // all at the same time.
10482        boolean repeat;
10483        do {
10484            repeat = false;
10485            for (int i=mRestartingServices.size()-1; i>=0; i--) {
10486                ServiceRecord r2 = mRestartingServices.get(i);
10487                if (r2 != r && r.nextRestartTime
10488                        >= (r2.nextRestartTime-SERVICE_MIN_RESTART_TIME_BETWEEN)
10489                        && r.nextRestartTime
10490                        < (r2.nextRestartTime+SERVICE_MIN_RESTART_TIME_BETWEEN)) {
10491                    r.nextRestartTime = r2.nextRestartTime + SERVICE_MIN_RESTART_TIME_BETWEEN;
10492                    r.restartDelay = r.nextRestartTime - now;
10493                    repeat = true;
10494                    break;
10495                }
10496            }
10497        } while (repeat);
10498
10499        if (!mRestartingServices.contains(r)) {
10500            mRestartingServices.add(r);
10501        }
10502
10503        r.cancelNotification();
10504
10505        mHandler.removeCallbacks(r.restarter);
10506        mHandler.postAtTime(r.restarter, r.nextRestartTime);
10507        r.nextRestartTime = SystemClock.uptimeMillis() + r.restartDelay;
10508        Log.w(TAG, "Scheduling restart of crashed service "
10509                + r.shortName + " in " + r.restartDelay + "ms");
10510        EventLog.writeEvent(LOG_AM_SCHEDULE_SERVICE_RESTART,
10511                r.shortName, r.restartDelay);
10512
10513        Message msg = Message.obtain();
10514        msg.what = SERVICE_ERROR_MSG;
10515        msg.obj = r;
10516        mHandler.sendMessage(msg);
10517
10518        return canceled;
10519    }
10520
10521    final void performServiceRestartLocked(ServiceRecord r) {
10522        if (!mRestartingServices.contains(r)) {
10523            return;
10524        }
10525        bringUpServiceLocked(r, r.intent.getIntent().getFlags(), true);
10526    }
10527
10528    private final boolean unscheduleServiceRestartLocked(ServiceRecord r) {
10529        if (r.restartDelay == 0) {
10530            return false;
10531        }
10532        r.resetRestartCounter();
10533        mRestartingServices.remove(r);
10534        mHandler.removeCallbacks(r.restarter);
10535        return true;
10536    }
10537
10538    private final boolean bringUpServiceLocked(ServiceRecord r,
10539            int intentFlags, boolean whileRestarting) {
10540        //Log.i(TAG, "Bring up service:");
10541        //r.dump("  ");
10542
10543        if (r.app != null && r.app.thread != null) {
10544            sendServiceArgsLocked(r, false);
10545            return true;
10546        }
10547
10548        if (!whileRestarting && r.restartDelay > 0) {
10549            // If waiting for a restart, then do nothing.
10550            return true;
10551        }
10552
10553        if (DEBUG_SERVICE) Log.v(TAG, "Bringing up service " + r.name
10554                + " " + r.intent);
10555
10556        // We are now bringing the service up, so no longer in the
10557        // restarting state.
10558        mRestartingServices.remove(r);
10559
10560        final String appName = r.processName;
10561        ProcessRecord app = getProcessRecordLocked(appName, r.appInfo.uid);
10562        if (app != null && app.thread != null) {
10563            try {
10564                realStartServiceLocked(r, app);
10565                return true;
10566            } catch (RemoteException e) {
10567                Log.w(TAG, "Exception when starting service " + r.shortName, e);
10568            }
10569
10570            // If a dead object exception was thrown -- fall through to
10571            // restart the application.
10572        }
10573
10574        // Not running -- get it started, and enqueue this service record
10575        // to be executed when the app comes up.
10576        if (startProcessLocked(appName, r.appInfo, true, intentFlags,
10577                "service", r.name, false) == null) {
10578            Log.w(TAG, "Unable to launch app "
10579                    + r.appInfo.packageName + "/"
10580                    + r.appInfo.uid + " for service "
10581                    + r.intent.getIntent() + ": process is bad");
10582            bringDownServiceLocked(r, true);
10583            return false;
10584        }
10585
10586        if (!mPendingServices.contains(r)) {
10587            mPendingServices.add(r);
10588        }
10589
10590        return true;
10591    }
10592
10593    private final void bringDownServiceLocked(ServiceRecord r, boolean force) {
10594        //Log.i(TAG, "Bring down service:");
10595        //r.dump("  ");
10596
10597        // Does it still need to run?
10598        if (!force && r.startRequested) {
10599            return;
10600        }
10601        if (r.connections.size() > 0) {
10602            if (!force) {
10603                // XXX should probably keep a count of the number of auto-create
10604                // connections directly in the service.
10605                Iterator<ConnectionRecord> it = r.connections.values().iterator();
10606                while (it.hasNext()) {
10607                    ConnectionRecord cr = it.next();
10608                    if ((cr.flags&Context.BIND_AUTO_CREATE) != 0) {
10609                        return;
10610                    }
10611                }
10612            }
10613
10614            // Report to all of the connections that the service is no longer
10615            // available.
10616            Iterator<ConnectionRecord> it = r.connections.values().iterator();
10617            while (it.hasNext()) {
10618                ConnectionRecord c = it.next();
10619                try {
10620                    // todo: shouldn't be a synchronous call!
10621                    c.conn.connected(r.name, null);
10622                } catch (Exception e) {
10623                    Log.w(TAG, "Failure disconnecting service " + r.name +
10624                          " to connection " + c.conn.asBinder() +
10625                          " (in " + c.binding.client.processName + ")", e);
10626                }
10627            }
10628        }
10629
10630        // Tell the service that it has been unbound.
10631        if (r.bindings.size() > 0 && r.app != null && r.app.thread != null) {
10632            Iterator<IntentBindRecord> it = r.bindings.values().iterator();
10633            while (it.hasNext()) {
10634                IntentBindRecord ibr = it.next();
10635                if (DEBUG_SERVICE) Log.v(TAG, "Bringing down binding " + ibr
10636                        + ": hasBound=" + ibr.hasBound);
10637                if (r.app != null && r.app.thread != null && ibr.hasBound) {
10638                    try {
10639                        bumpServiceExecutingLocked(r);
10640                        updateOomAdjLocked(r.app);
10641                        ibr.hasBound = false;
10642                        r.app.thread.scheduleUnbindService(r,
10643                                ibr.intent.getIntent());
10644                    } catch (Exception e) {
10645                        Log.w(TAG, "Exception when unbinding service "
10646                                + r.shortName, e);
10647                        serviceDoneExecutingLocked(r, true);
10648                    }
10649                }
10650            }
10651        }
10652
10653        if (DEBUG_SERVICE) Log.v(TAG, "Bringing down service " + r.name
10654                 + " " + r.intent);
10655        EventLog.writeEvent(LOG_AM_DESTROY_SERVICE,
10656                System.identityHashCode(r), r.shortName,
10657                (r.app != null) ? r.app.pid : -1);
10658
10659        mServices.remove(r.name);
10660        mServicesByIntent.remove(r.intent);
10661        if (localLOGV) Log.v(TAG, "BRING DOWN SERVICE: " + r.shortName);
10662        r.totalRestartCount = 0;
10663        unscheduleServiceRestartLocked(r);
10664
10665        // Also make sure it is not on the pending list.
10666        int N = mPendingServices.size();
10667        for (int i=0; i<N; i++) {
10668            if (mPendingServices.get(i) == r) {
10669                mPendingServices.remove(i);
10670                if (DEBUG_SERVICE) Log.v(
10671                    TAG, "Removed pending service: " + r.shortName);
10672                i--;
10673                N--;
10674            }
10675        }
10676
10677        r.cancelNotification();
10678        r.isForeground = false;
10679        r.foregroundId = 0;
10680        r.foregroundNoti = null;
10681
10682        // Clear start entries.
10683        r.deliveredStarts.clear();
10684        r.pendingStarts.clear();
10685
10686        if (r.app != null) {
10687            synchronized (r.stats.getBatteryStats()) {
10688                r.stats.stopLaunchedLocked();
10689            }
10690            r.app.services.remove(r);
10691            if (r.app.thread != null) {
10692                try {
10693                    if (DEBUG_SERVICE) Log.v(TAG,
10694                            "Stopping service: " + r.shortName);
10695                    bumpServiceExecutingLocked(r);
10696                    mStoppingServices.add(r);
10697                    updateOomAdjLocked(r.app);
10698                    r.app.thread.scheduleStopService(r);
10699                } catch (Exception e) {
10700                    Log.w(TAG, "Exception when stopping service "
10701                            + r.shortName, e);
10702                    serviceDoneExecutingLocked(r, true);
10703                }
10704                updateServiceForegroundLocked(r.app, false);
10705            } else {
10706                if (DEBUG_SERVICE) Log.v(
10707                    TAG, "Removed service that has no process: " + r.shortName);
10708            }
10709        } else {
10710            if (DEBUG_SERVICE) Log.v(
10711                TAG, "Removed service that is not running: " + r.shortName);
10712        }
10713    }
10714
10715    ComponentName startServiceLocked(IApplicationThread caller,
10716            Intent service, String resolvedType,
10717            int callingPid, int callingUid) {
10718        synchronized(this) {
10719            if (DEBUG_SERVICE) Log.v(TAG, "startService: " + service
10720                    + " type=" + resolvedType + " args=" + service.getExtras());
10721
10722            if (caller != null) {
10723                final ProcessRecord callerApp = getRecordForAppLocked(caller);
10724                if (callerApp == null) {
10725                    throw new SecurityException(
10726                            "Unable to find app for caller " + caller
10727                            + " (pid=" + Binder.getCallingPid()
10728                            + ") when starting service " + service);
10729                }
10730            }
10731
10732            ServiceLookupResult res =
10733                retrieveServiceLocked(service, resolvedType,
10734                        callingPid, callingUid);
10735            if (res == null) {
10736                return null;
10737            }
10738            if (res.record == null) {
10739                return new ComponentName("!", res.permission != null
10740                        ? res.permission : "private to package");
10741            }
10742            ServiceRecord r = res.record;
10743            if (unscheduleServiceRestartLocked(r)) {
10744                if (DEBUG_SERVICE) Log.v(TAG, "START SERVICE WHILE RESTART PENDING: "
10745                        + r.shortName);
10746            }
10747            r.startRequested = true;
10748            r.callStart = false;
10749            r.lastStartId++;
10750            if (r.lastStartId < 1) {
10751                r.lastStartId = 1;
10752            }
10753            r.pendingStarts.add(new ServiceRecord.StartItem(r.lastStartId, service));
10754            r.lastActivity = SystemClock.uptimeMillis();
10755            synchronized (r.stats.getBatteryStats()) {
10756                r.stats.startRunningLocked();
10757            }
10758            if (!bringUpServiceLocked(r, service.getFlags(), false)) {
10759                return new ComponentName("!", "Service process is bad");
10760            }
10761            return r.name;
10762        }
10763    }
10764
10765    public ComponentName startService(IApplicationThread caller, Intent service,
10766            String resolvedType) {
10767        // Refuse possible leaked file descriptors
10768        if (service != null && service.hasFileDescriptors() == true) {
10769            throw new IllegalArgumentException("File descriptors passed in Intent");
10770        }
10771
10772        synchronized(this) {
10773            final int callingPid = Binder.getCallingPid();
10774            final int callingUid = Binder.getCallingUid();
10775            final long origId = Binder.clearCallingIdentity();
10776            ComponentName res = startServiceLocked(caller, service,
10777                    resolvedType, callingPid, callingUid);
10778            Binder.restoreCallingIdentity(origId);
10779            return res;
10780        }
10781    }
10782
10783    ComponentName startServiceInPackage(int uid,
10784            Intent service, String resolvedType) {
10785        synchronized(this) {
10786            final long origId = Binder.clearCallingIdentity();
10787            ComponentName res = startServiceLocked(null, service,
10788                    resolvedType, -1, uid);
10789            Binder.restoreCallingIdentity(origId);
10790            return res;
10791        }
10792    }
10793
10794    public int stopService(IApplicationThread caller, Intent service,
10795            String resolvedType) {
10796        // Refuse possible leaked file descriptors
10797        if (service != null && service.hasFileDescriptors() == true) {
10798            throw new IllegalArgumentException("File descriptors passed in Intent");
10799        }
10800
10801        synchronized(this) {
10802            if (DEBUG_SERVICE) Log.v(TAG, "stopService: " + service
10803                    + " type=" + resolvedType);
10804
10805            final ProcessRecord callerApp = getRecordForAppLocked(caller);
10806            if (caller != null && callerApp == null) {
10807                throw new SecurityException(
10808                        "Unable to find app for caller " + caller
10809                        + " (pid=" + Binder.getCallingPid()
10810                        + ") when stopping service " + service);
10811            }
10812
10813            // If this service is active, make sure it is stopped.
10814            ServiceLookupResult r = findServiceLocked(service, resolvedType);
10815            if (r != null) {
10816                if (r.record != null) {
10817                    synchronized (r.record.stats.getBatteryStats()) {
10818                        r.record.stats.stopRunningLocked();
10819                    }
10820                    r.record.startRequested = false;
10821                    r.record.callStart = false;
10822                    final long origId = Binder.clearCallingIdentity();
10823                    bringDownServiceLocked(r.record, false);
10824                    Binder.restoreCallingIdentity(origId);
10825                    return 1;
10826                }
10827                return -1;
10828            }
10829        }
10830
10831        return 0;
10832    }
10833
10834    public IBinder peekService(Intent service, String resolvedType) {
10835        // Refuse possible leaked file descriptors
10836        if (service != null && service.hasFileDescriptors() == true) {
10837            throw new IllegalArgumentException("File descriptors passed in Intent");
10838        }
10839
10840        IBinder ret = null;
10841
10842        synchronized(this) {
10843            ServiceLookupResult r = findServiceLocked(service, resolvedType);
10844
10845            if (r != null) {
10846                // r.record is null if findServiceLocked() failed the caller permission check
10847                if (r.record == null) {
10848                    throw new SecurityException(
10849                            "Permission Denial: Accessing service " + r.record.name
10850                            + " from pid=" + Binder.getCallingPid()
10851                            + ", uid=" + Binder.getCallingUid()
10852                            + " requires " + r.permission);
10853                }
10854                IntentBindRecord ib = r.record.bindings.get(r.record.intent);
10855                if (ib != null) {
10856                    ret = ib.binder;
10857                }
10858            }
10859        }
10860
10861        return ret;
10862    }
10863
10864    public boolean stopServiceToken(ComponentName className, IBinder token,
10865            int startId) {
10866        synchronized(this) {
10867            if (DEBUG_SERVICE) Log.v(TAG, "stopServiceToken: " + className
10868                    + " " + token + " startId=" + startId);
10869            ServiceRecord r = findServiceLocked(className, token);
10870            if (r != null) {
10871                if (startId >= 0) {
10872                    // Asked to only stop if done with all work.  Note that
10873                    // to avoid leaks, we will take this as dropping all
10874                    // start items up to and including this one.
10875                    ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
10876                    if (si != null) {
10877                        while (r.deliveredStarts.size() > 0) {
10878                            if (r.deliveredStarts.remove(0) == si) {
10879                                break;
10880                            }
10881                        }
10882                    }
10883
10884                    if (r.lastStartId != startId) {
10885                        return false;
10886                    }
10887
10888                    if (r.deliveredStarts.size() > 0) {
10889                        Log.w(TAG, "stopServiceToken startId " + startId
10890                                + " is last, but have " + r.deliveredStarts.size()
10891                                + " remaining args");
10892                    }
10893                }
10894
10895                synchronized (r.stats.getBatteryStats()) {
10896                    r.stats.stopRunningLocked();
10897                    r.startRequested = false;
10898                    r.callStart = false;
10899                }
10900                final long origId = Binder.clearCallingIdentity();
10901                bringDownServiceLocked(r, false);
10902                Binder.restoreCallingIdentity(origId);
10903                return true;
10904            }
10905        }
10906        return false;
10907    }
10908
10909    public void setServiceForeground(ComponentName className, IBinder token,
10910            int id, Notification notification, boolean removeNotification) {
10911        final long origId = Binder.clearCallingIdentity();
10912        try {
10913        synchronized(this) {
10914            ServiceRecord r = findServiceLocked(className, token);
10915            if (r != null) {
10916                if (id != 0) {
10917                    if (notification == null) {
10918                        throw new IllegalArgumentException("null notification");
10919                    }
10920                    if (r.foregroundId != id) {
10921                        r.cancelNotification();
10922                        r.foregroundId = id;
10923                    }
10924                    notification.flags |= Notification.FLAG_FOREGROUND_SERVICE;
10925                    r.foregroundNoti = notification;
10926                    r.isForeground = true;
10927                    r.postNotification();
10928                    if (r.app != null) {
10929                        updateServiceForegroundLocked(r.app, true);
10930                    }
10931                } else {
10932                    if (r.isForeground) {
10933                        r.isForeground = false;
10934                        if (r.app != null) {
10935                            updateServiceForegroundLocked(r.app, true);
10936                        }
10937                    }
10938                    if (removeNotification) {
10939                        r.cancelNotification();
10940                        r.foregroundId = 0;
10941                        r.foregroundNoti = null;
10942                    }
10943                }
10944            }
10945        }
10946        } finally {
10947            Binder.restoreCallingIdentity(origId);
10948        }
10949    }
10950
10951    public void updateServiceForegroundLocked(ProcessRecord proc, boolean oomAdj) {
10952        boolean anyForeground = false;
10953        for (ServiceRecord sr : (HashSet<ServiceRecord>)proc.services) {
10954            if (sr.isForeground) {
10955                anyForeground = true;
10956                break;
10957            }
10958        }
10959        if (anyForeground != proc.foregroundServices) {
10960            proc.foregroundServices = anyForeground;
10961            if (oomAdj) {
10962                updateOomAdjLocked();
10963            }
10964        }
10965    }
10966
10967    public int bindService(IApplicationThread caller, IBinder token,
10968            Intent service, String resolvedType,
10969            IServiceConnection connection, int flags) {
10970        // Refuse possible leaked file descriptors
10971        if (service != null && service.hasFileDescriptors() == true) {
10972            throw new IllegalArgumentException("File descriptors passed in Intent");
10973        }
10974
10975        synchronized(this) {
10976            if (DEBUG_SERVICE) Log.v(TAG, "bindService: " + service
10977                    + " type=" + resolvedType + " conn=" + connection.asBinder()
10978                    + " flags=0x" + Integer.toHexString(flags));
10979            final ProcessRecord callerApp = getRecordForAppLocked(caller);
10980            if (callerApp == null) {
10981                throw new SecurityException(
10982                        "Unable to find app for caller " + caller
10983                        + " (pid=" + Binder.getCallingPid()
10984                        + ") when binding service " + service);
10985            }
10986
10987            HistoryRecord activity = null;
10988            if (token != null) {
10989                int aindex = indexOfTokenLocked(token);
10990                if (aindex < 0) {
10991                    Log.w(TAG, "Binding with unknown activity: " + token);
10992                    return 0;
10993                }
10994                activity = (HistoryRecord)mHistory.get(aindex);
10995            }
10996
10997            int clientLabel = 0;
10998            PendingIntent clientIntent = null;
10999
11000            if (callerApp.info.uid == Process.SYSTEM_UID) {
11001                // Hacky kind of thing -- allow system stuff to tell us
11002                // what they are, so we can report this elsewhere for
11003                // others to know why certain services are running.
11004                try {
11005                    clientIntent = (PendingIntent)service.getParcelableExtra(
11006                            Intent.EXTRA_CLIENT_INTENT);
11007                } catch (RuntimeException e) {
11008                }
11009                if (clientIntent != null) {
11010                    clientLabel = service.getIntExtra(Intent.EXTRA_CLIENT_LABEL, 0);
11011                    if (clientLabel != 0) {
11012                        // There are no useful extras in the intent, trash them.
11013                        // System code calling with this stuff just needs to know
11014                        // this will happen.
11015                        service = service.cloneFilter();
11016                    }
11017                }
11018            }
11019
11020            ServiceLookupResult res =
11021                retrieveServiceLocked(service, resolvedType,
11022                        Binder.getCallingPid(), Binder.getCallingUid());
11023            if (res == null) {
11024                return 0;
11025            }
11026            if (res.record == null) {
11027                return -1;
11028            }
11029            ServiceRecord s = res.record;
11030
11031            final long origId = Binder.clearCallingIdentity();
11032
11033            if (unscheduleServiceRestartLocked(s)) {
11034                if (DEBUG_SERVICE) Log.v(TAG, "BIND SERVICE WHILE RESTART PENDING: "
11035                        + s.shortName);
11036            }
11037
11038            AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
11039            ConnectionRecord c = new ConnectionRecord(b, activity,
11040                    connection, flags, clientLabel, clientIntent);
11041
11042            IBinder binder = connection.asBinder();
11043            s.connections.put(binder, c);
11044            b.connections.add(c);
11045            if (activity != null) {
11046                if (activity.connections == null) {
11047                    activity.connections = new HashSet<ConnectionRecord>();
11048                }
11049                activity.connections.add(c);
11050            }
11051            b.client.connections.add(c);
11052            mServiceConnections.put(binder, c);
11053
11054            if ((flags&Context.BIND_AUTO_CREATE) != 0) {
11055                s.lastActivity = SystemClock.uptimeMillis();
11056                if (!bringUpServiceLocked(s, service.getFlags(), false)) {
11057                    return 0;
11058                }
11059            }
11060
11061            if (s.app != null) {
11062                // This could have made the service more important.
11063                updateOomAdjLocked(s.app);
11064            }
11065
11066            if (DEBUG_SERVICE) Log.v(TAG, "Bind " + s + " with " + b
11067                    + ": received=" + b.intent.received
11068                    + " apps=" + b.intent.apps.size()
11069                    + " doRebind=" + b.intent.doRebind);
11070
11071            if (s.app != null && b.intent.received) {
11072                // Service is already running, so we can immediately
11073                // publish the connection.
11074                try {
11075                    c.conn.connected(s.name, b.intent.binder);
11076                } catch (Exception e) {
11077                    Log.w(TAG, "Failure sending service " + s.shortName
11078                            + " to connection " + c.conn.asBinder()
11079                            + " (in " + c.binding.client.processName + ")", e);
11080                }
11081
11082                // If this is the first app connected back to this binding,
11083                // and the service had previously asked to be told when
11084                // rebound, then do so.
11085                if (b.intent.apps.size() == 1 && b.intent.doRebind) {
11086                    requestServiceBindingLocked(s, b.intent, true);
11087                }
11088            } else if (!b.intent.requested) {
11089                requestServiceBindingLocked(s, b.intent, false);
11090            }
11091
11092            Binder.restoreCallingIdentity(origId);
11093        }
11094
11095        return 1;
11096    }
11097
11098    private void removeConnectionLocked(
11099        ConnectionRecord c, ProcessRecord skipApp, HistoryRecord skipAct) {
11100        IBinder binder = c.conn.asBinder();
11101        AppBindRecord b = c.binding;
11102        ServiceRecord s = b.service;
11103        s.connections.remove(binder);
11104        b.connections.remove(c);
11105        if (c.activity != null && c.activity != skipAct) {
11106            if (c.activity.connections != null) {
11107                c.activity.connections.remove(c);
11108            }
11109        }
11110        if (b.client != skipApp) {
11111            b.client.connections.remove(c);
11112        }
11113        mServiceConnections.remove(binder);
11114
11115        if (b.connections.size() == 0) {
11116            b.intent.apps.remove(b.client);
11117        }
11118
11119        if (DEBUG_SERVICE) Log.v(TAG, "Disconnecting binding " + b.intent
11120                + ": shouldUnbind=" + b.intent.hasBound);
11121        if (s.app != null && s.app.thread != null && b.intent.apps.size() == 0
11122                && b.intent.hasBound) {
11123            try {
11124                bumpServiceExecutingLocked(s);
11125                updateOomAdjLocked(s.app);
11126                b.intent.hasBound = false;
11127                // Assume the client doesn't want to know about a rebind;
11128                // we will deal with that later if it asks for one.
11129                b.intent.doRebind = false;
11130                s.app.thread.scheduleUnbindService(s, b.intent.intent.getIntent());
11131            } catch (Exception e) {
11132                Log.w(TAG, "Exception when unbinding service " + s.shortName, e);
11133                serviceDoneExecutingLocked(s, true);
11134            }
11135        }
11136
11137        if ((c.flags&Context.BIND_AUTO_CREATE) != 0) {
11138            bringDownServiceLocked(s, false);
11139        }
11140    }
11141
11142    public boolean unbindService(IServiceConnection connection) {
11143        synchronized (this) {
11144            IBinder binder = connection.asBinder();
11145            if (DEBUG_SERVICE) Log.v(TAG, "unbindService: conn=" + binder);
11146            ConnectionRecord r = mServiceConnections.get(binder);
11147            if (r == null) {
11148                Log.w(TAG, "Unbind failed: could not find connection for "
11149                      + connection.asBinder());
11150                return false;
11151            }
11152
11153            final long origId = Binder.clearCallingIdentity();
11154
11155            removeConnectionLocked(r, null, null);
11156
11157            if (r.binding.service.app != null) {
11158                // This could have made the service less important.
11159                updateOomAdjLocked(r.binding.service.app);
11160            }
11161
11162            Binder.restoreCallingIdentity(origId);
11163        }
11164
11165        return true;
11166    }
11167
11168    public void publishService(IBinder token, Intent intent, IBinder service) {
11169        // Refuse possible leaked file descriptors
11170        if (intent != null && intent.hasFileDescriptors() == true) {
11171            throw new IllegalArgumentException("File descriptors passed in Intent");
11172        }
11173
11174        synchronized(this) {
11175            if (!(token instanceof ServiceRecord)) {
11176                throw new IllegalArgumentException("Invalid service token");
11177            }
11178            ServiceRecord r = (ServiceRecord)token;
11179
11180            final long origId = Binder.clearCallingIdentity();
11181
11182            if (DEBUG_SERVICE) Log.v(TAG, "PUBLISHING SERVICE " + r.name
11183                    + " " + intent + ": " + service);
11184            if (r != null) {
11185                Intent.FilterComparison filter
11186                        = new Intent.FilterComparison(intent);
11187                IntentBindRecord b = r.bindings.get(filter);
11188                if (b != null && !b.received) {
11189                    b.binder = service;
11190                    b.requested = true;
11191                    b.received = true;
11192                    if (r.connections.size() > 0) {
11193                        Iterator<ConnectionRecord> it
11194                                = r.connections.values().iterator();
11195                        while (it.hasNext()) {
11196                            ConnectionRecord c = it.next();
11197                            if (!filter.equals(c.binding.intent.intent)) {
11198                                if (DEBUG_SERVICE) Log.v(
11199                                        TAG, "Not publishing to: " + c);
11200                                if (DEBUG_SERVICE) Log.v(
11201                                        TAG, "Bound intent: " + c.binding.intent.intent);
11202                                if (DEBUG_SERVICE) Log.v(
11203                                        TAG, "Published intent: " + intent);
11204                                continue;
11205                            }
11206                            if (DEBUG_SERVICE) Log.v(TAG, "Publishing to: " + c);
11207                            try {
11208                                c.conn.connected(r.name, service);
11209                            } catch (Exception e) {
11210                                Log.w(TAG, "Failure sending service " + r.name +
11211                                      " to connection " + c.conn.asBinder() +
11212                                      " (in " + c.binding.client.processName + ")", e);
11213                            }
11214                        }
11215                    }
11216                }
11217
11218                serviceDoneExecutingLocked(r, mStoppingServices.contains(r));
11219
11220                Binder.restoreCallingIdentity(origId);
11221            }
11222        }
11223    }
11224
11225    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
11226        // Refuse possible leaked file descriptors
11227        if (intent != null && intent.hasFileDescriptors() == true) {
11228            throw new IllegalArgumentException("File descriptors passed in Intent");
11229        }
11230
11231        synchronized(this) {
11232            if (!(token instanceof ServiceRecord)) {
11233                throw new IllegalArgumentException("Invalid service token");
11234            }
11235            ServiceRecord r = (ServiceRecord)token;
11236
11237            final long origId = Binder.clearCallingIdentity();
11238
11239            if (r != null) {
11240                Intent.FilterComparison filter
11241                        = new Intent.FilterComparison(intent);
11242                IntentBindRecord b = r.bindings.get(filter);
11243                if (DEBUG_SERVICE) Log.v(TAG, "unbindFinished in " + r
11244                        + " at " + b + ": apps="
11245                        + (b != null ? b.apps.size() : 0));
11246                if (b != null) {
11247                    if (b.apps.size() > 0) {
11248                        // Applications have already bound since the last
11249                        // unbind, so just rebind right here.
11250                        requestServiceBindingLocked(r, b, true);
11251                    } else {
11252                        // Note to tell the service the next time there is
11253                        // a new client.
11254                        b.doRebind = true;
11255                    }
11256                }
11257
11258                serviceDoneExecutingLocked(r, mStoppingServices.contains(r));
11259
11260                Binder.restoreCallingIdentity(origId);
11261            }
11262        }
11263    }
11264
11265    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
11266        synchronized(this) {
11267            if (!(token instanceof ServiceRecord)) {
11268                throw new IllegalArgumentException("Invalid service token");
11269            }
11270            ServiceRecord r = (ServiceRecord)token;
11271            boolean inStopping = mStoppingServices.contains(token);
11272            if (r != null) {
11273                if (DEBUG_SERVICE) Log.v(TAG, "DONE EXECUTING SERVICE " + r.name
11274                        + ": nesting=" + r.executeNesting
11275                        + ", inStopping=" + inStopping);
11276                if (r != token) {
11277                    Log.w(TAG, "Done executing service " + r.name
11278                          + " with incorrect token: given " + token
11279                          + ", expected " + r);
11280                    return;
11281                }
11282
11283                if (type == 1) {
11284                    // This is a call from a service start...  take care of
11285                    // book-keeping.
11286                    r.callStart = true;
11287                    switch (res) {
11288                        case Service.START_STICKY_COMPATIBILITY:
11289                        case Service.START_STICKY: {
11290                            // We are done with the associated start arguments.
11291                            r.findDeliveredStart(startId, true);
11292                            // Don't stop if killed.
11293                            r.stopIfKilled = false;
11294                            break;
11295                        }
11296                        case Service.START_NOT_STICKY: {
11297                            // We are done with the associated start arguments.
11298                            r.findDeliveredStart(startId, true);
11299                            if (r.lastStartId == startId) {
11300                                // There is no more work, and this service
11301                                // doesn't want to hang around if killed.
11302                                r.stopIfKilled = true;
11303                            }
11304                            break;
11305                        }
11306                        case Service.START_REDELIVER_INTENT: {
11307                            // We'll keep this item until they explicitly
11308                            // call stop for it, but keep track of the fact
11309                            // that it was delivered.
11310                            ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
11311                            if (si != null) {
11312                                si.deliveryCount = 0;
11313                                si.doneExecutingCount++;
11314                                // Don't stop if killed.
11315                                r.stopIfKilled = true;
11316                            }
11317                            break;
11318                        }
11319                        default:
11320                            throw new IllegalArgumentException(
11321                                    "Unknown service start result: " + res);
11322                    }
11323                    if (res == Service.START_STICKY_COMPATIBILITY) {
11324                        r.callStart = false;
11325                    }
11326                }
11327
11328                final long origId = Binder.clearCallingIdentity();
11329                serviceDoneExecutingLocked(r, inStopping);
11330                Binder.restoreCallingIdentity(origId);
11331            } else {
11332                Log.w(TAG, "Done executing unknown service " + r.name
11333                        + " with token " + token);
11334            }
11335        }
11336    }
11337
11338    public void serviceDoneExecutingLocked(ServiceRecord r, boolean inStopping) {
11339        r.executeNesting--;
11340        if (r.executeNesting <= 0 && r.app != null) {
11341            r.app.executingServices.remove(r);
11342            if (r.app.executingServices.size() == 0) {
11343                mHandler.removeMessages(SERVICE_TIMEOUT_MSG, r.app);
11344            }
11345            if (inStopping) {
11346                mStoppingServices.remove(r);
11347            }
11348            updateOomAdjLocked(r.app);
11349        }
11350    }
11351
11352    void serviceTimeout(ProcessRecord proc) {
11353        synchronized(this) {
11354            if (proc.executingServices.size() == 0 || proc.thread == null) {
11355                return;
11356            }
11357            long maxTime = SystemClock.uptimeMillis() - SERVICE_TIMEOUT;
11358            Iterator<ServiceRecord> it = proc.executingServices.iterator();
11359            ServiceRecord timeout = null;
11360            long nextTime = 0;
11361            while (it.hasNext()) {
11362                ServiceRecord sr = it.next();
11363                if (sr.executingStart < maxTime) {
11364                    timeout = sr;
11365                    break;
11366                }
11367                if (sr.executingStart > nextTime) {
11368                    nextTime = sr.executingStart;
11369                }
11370            }
11371            if (timeout != null && mLRUProcesses.contains(proc)) {
11372                Log.w(TAG, "Timeout executing service: " + timeout);
11373                appNotRespondingLocked(proc, null, null, "Executing service "
11374                        + timeout.name);
11375            } else {
11376                Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
11377                msg.obj = proc;
11378                mHandler.sendMessageAtTime(msg, nextTime+SERVICE_TIMEOUT);
11379            }
11380        }
11381    }
11382
11383    // =========================================================
11384    // BACKUP AND RESTORE
11385    // =========================================================
11386
11387    // Cause the target app to be launched if necessary and its backup agent
11388    // instantiated.  The backup agent will invoke backupAgentCreated() on the
11389    // activity manager to announce its creation.
11390    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
11391        if (DEBUG_BACKUP) Log.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode);
11392        enforceCallingPermission("android.permission.BACKUP", "startBackupAgent");
11393
11394        synchronized(this) {
11395            // !!! TODO: currently no check here that we're already bound
11396            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
11397            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11398            synchronized (stats) {
11399                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
11400            }
11401
11402            BackupRecord r = new BackupRecord(ss, app, backupMode);
11403            ComponentName hostingName = new ComponentName(app.packageName, app.backupAgentName);
11404            // startProcessLocked() returns existing proc's record if it's already running
11405            ProcessRecord proc = startProcessLocked(app.processName, app,
11406                    false, 0, "backup", hostingName, false);
11407            if (proc == null) {
11408                Log.e(TAG, "Unable to start backup agent process " + r);
11409                return false;
11410            }
11411
11412            r.app = proc;
11413            mBackupTarget = r;
11414            mBackupAppName = app.packageName;
11415
11416            // Try not to kill the process during backup
11417            updateOomAdjLocked(proc);
11418
11419            // If the process is already attached, schedule the creation of the backup agent now.
11420            // If it is not yet live, this will be done when it attaches to the framework.
11421            if (proc.thread != null) {
11422                if (DEBUG_BACKUP) Log.v(TAG, "Agent proc already running: " + proc);
11423                try {
11424                    proc.thread.scheduleCreateBackupAgent(app, backupMode);
11425                } catch (RemoteException e) {
11426                    // Will time out on the backup manager side
11427                }
11428            } else {
11429                if (DEBUG_BACKUP) Log.v(TAG, "Agent proc not running, waiting for attach");
11430            }
11431            // Invariants: at this point, the target app process exists and the application
11432            // is either already running or in the process of coming up.  mBackupTarget and
11433            // mBackupAppName describe the app, so that when it binds back to the AM we
11434            // know that it's scheduled for a backup-agent operation.
11435        }
11436
11437        return true;
11438    }
11439
11440    // A backup agent has just come up
11441    public void backupAgentCreated(String agentPackageName, IBinder agent) {
11442        if (DEBUG_BACKUP) Log.v(TAG, "backupAgentCreated: " + agentPackageName
11443                + " = " + agent);
11444
11445        synchronized(this) {
11446            if (!agentPackageName.equals(mBackupAppName)) {
11447                Log.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
11448                return;
11449            }
11450
11451            long oldIdent = Binder.clearCallingIdentity();
11452            try {
11453                IBackupManager bm = IBackupManager.Stub.asInterface(
11454                        ServiceManager.getService(Context.BACKUP_SERVICE));
11455                bm.agentConnected(agentPackageName, agent);
11456            } catch (RemoteException e) {
11457                // can't happen; the backup manager service is local
11458            } catch (Exception e) {
11459                Log.w(TAG, "Exception trying to deliver BackupAgent binding: ");
11460                e.printStackTrace();
11461            } finally {
11462                Binder.restoreCallingIdentity(oldIdent);
11463            }
11464        }
11465    }
11466
11467    // done with this agent
11468    public void unbindBackupAgent(ApplicationInfo appInfo) {
11469        if (DEBUG_BACKUP) Log.v(TAG, "unbindBackupAgent: " + appInfo);
11470        if (appInfo == null) {
11471            Log.w(TAG, "unbind backup agent for null app");
11472            return;
11473        }
11474
11475        synchronized(this) {
11476            if (mBackupAppName == null) {
11477                Log.w(TAG, "Unbinding backup agent with no active backup");
11478                return;
11479            }
11480
11481            if (!mBackupAppName.equals(appInfo.packageName)) {
11482                Log.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
11483                return;
11484            }
11485
11486            ProcessRecord proc = mBackupTarget.app;
11487            mBackupTarget = null;
11488            mBackupAppName = null;
11489
11490            // Not backing this app up any more; reset its OOM adjustment
11491            updateOomAdjLocked(proc);
11492
11493            // If the app crashed during backup, 'thread' will be null here
11494            if (proc.thread != null) {
11495                try {
11496                    proc.thread.scheduleDestroyBackupAgent(appInfo);
11497                } catch (Exception e) {
11498                    Log.e(TAG, "Exception when unbinding backup agent:");
11499                    e.printStackTrace();
11500                }
11501            }
11502        }
11503    }
11504    // =========================================================
11505    // BROADCASTS
11506    // =========================================================
11507
11508    private final List getStickies(String action, IntentFilter filter,
11509            List cur) {
11510        final ContentResolver resolver = mContext.getContentResolver();
11511        final ArrayList<Intent> list = mStickyBroadcasts.get(action);
11512        if (list == null) {
11513            return cur;
11514        }
11515        int N = list.size();
11516        for (int i=0; i<N; i++) {
11517            Intent intent = list.get(i);
11518            if (filter.match(resolver, intent, true, TAG) >= 0) {
11519                if (cur == null) {
11520                    cur = new ArrayList<Intent>();
11521                }
11522                cur.add(intent);
11523            }
11524        }
11525        return cur;
11526    }
11527
11528    private final void scheduleBroadcastsLocked() {
11529        if (DEBUG_BROADCAST) Log.v(TAG, "Schedule broadcasts: current="
11530                + mBroadcastsScheduled);
11531
11532        if (mBroadcastsScheduled) {
11533            return;
11534        }
11535        mHandler.sendEmptyMessage(BROADCAST_INTENT_MSG);
11536        mBroadcastsScheduled = true;
11537    }
11538
11539    public Intent registerReceiver(IApplicationThread caller,
11540            IIntentReceiver receiver, IntentFilter filter, String permission) {
11541        synchronized(this) {
11542            ProcessRecord callerApp = null;
11543            if (caller != null) {
11544                callerApp = getRecordForAppLocked(caller);
11545                if (callerApp == null) {
11546                    throw new SecurityException(
11547                            "Unable to find app for caller " + caller
11548                            + " (pid=" + Binder.getCallingPid()
11549                            + ") when registering receiver " + receiver);
11550                }
11551            }
11552
11553            List allSticky = null;
11554
11555            // Look for any matching sticky broadcasts...
11556            Iterator actions = filter.actionsIterator();
11557            if (actions != null) {
11558                while (actions.hasNext()) {
11559                    String action = (String)actions.next();
11560                    allSticky = getStickies(action, filter, allSticky);
11561                }
11562            } else {
11563                allSticky = getStickies(null, filter, allSticky);
11564            }
11565
11566            // The first sticky in the list is returned directly back to
11567            // the client.
11568            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
11569
11570            if (DEBUG_BROADCAST) Log.v(TAG, "Register receiver " + filter
11571                    + ": " + sticky);
11572
11573            if (receiver == null) {
11574                return sticky;
11575            }
11576
11577            ReceiverList rl
11578                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11579            if (rl == null) {
11580                rl = new ReceiverList(this, callerApp,
11581                        Binder.getCallingPid(),
11582                        Binder.getCallingUid(), receiver);
11583                if (rl.app != null) {
11584                    rl.app.receivers.add(rl);
11585                } else {
11586                    try {
11587                        receiver.asBinder().linkToDeath(rl, 0);
11588                    } catch (RemoteException e) {
11589                        return sticky;
11590                    }
11591                    rl.linkedToDeath = true;
11592                }
11593                mRegisteredReceivers.put(receiver.asBinder(), rl);
11594            }
11595            BroadcastFilter bf = new BroadcastFilter(filter, rl, permission);
11596            rl.add(bf);
11597            if (!bf.debugCheck()) {
11598                Log.w(TAG, "==> For Dynamic broadast");
11599            }
11600            mReceiverResolver.addFilter(bf);
11601
11602            // Enqueue broadcasts for all existing stickies that match
11603            // this filter.
11604            if (allSticky != null) {
11605                ArrayList receivers = new ArrayList();
11606                receivers.add(bf);
11607
11608                int N = allSticky.size();
11609                for (int i=0; i<N; i++) {
11610                    Intent intent = (Intent)allSticky.get(i);
11611                    BroadcastRecord r = new BroadcastRecord(intent, null,
11612                            null, -1, -1, null, receivers, null, 0, null, null,
11613                            false, true);
11614                    if (mParallelBroadcasts.size() == 0) {
11615                        scheduleBroadcastsLocked();
11616                    }
11617                    mParallelBroadcasts.add(r);
11618                }
11619            }
11620
11621            return sticky;
11622        }
11623    }
11624
11625    public void unregisterReceiver(IIntentReceiver receiver) {
11626        if (DEBUG_BROADCAST) Log.v(TAG, "Unregister receiver: " + receiver);
11627
11628        boolean doNext = false;
11629
11630        synchronized(this) {
11631            ReceiverList rl
11632                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11633            if (rl != null) {
11634                if (rl.curBroadcast != null) {
11635                    BroadcastRecord r = rl.curBroadcast;
11636                    doNext = finishReceiverLocked(
11637                        receiver.asBinder(), r.resultCode, r.resultData,
11638                        r.resultExtras, r.resultAbort, true);
11639                }
11640
11641                if (rl.app != null) {
11642                    rl.app.receivers.remove(rl);
11643                }
11644                removeReceiverLocked(rl);
11645                if (rl.linkedToDeath) {
11646                    rl.linkedToDeath = false;
11647                    rl.receiver.asBinder().unlinkToDeath(rl, 0);
11648                }
11649            }
11650        }
11651
11652        if (!doNext) {
11653            return;
11654        }
11655
11656        final long origId = Binder.clearCallingIdentity();
11657        processNextBroadcast(false);
11658        trimApplications();
11659        Binder.restoreCallingIdentity(origId);
11660    }
11661
11662    void removeReceiverLocked(ReceiverList rl) {
11663        mRegisteredReceivers.remove(rl.receiver.asBinder());
11664        int N = rl.size();
11665        for (int i=0; i<N; i++) {
11666            mReceiverResolver.removeFilter(rl.get(i));
11667        }
11668    }
11669
11670    private final int broadcastIntentLocked(ProcessRecord callerApp,
11671            String callerPackage, Intent intent, String resolvedType,
11672            IIntentReceiver resultTo, int resultCode, String resultData,
11673            Bundle map, String requiredPermission,
11674            boolean ordered, boolean sticky, int callingPid, int callingUid) {
11675        intent = new Intent(intent);
11676
11677        if (DEBUG_BROADCAST_LIGHT) Log.v(
11678            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
11679            + " ordered=" + ordered);
11680        if ((resultTo != null) && !ordered) {
11681            Log.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
11682        }
11683
11684        // Handle special intents: if this broadcast is from the package
11685        // manager about a package being removed, we need to remove all of
11686        // its activities from the history stack.
11687        final boolean uidRemoved = intent.ACTION_UID_REMOVED.equals(
11688                intent.getAction());
11689        if (intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
11690                || intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
11691                || uidRemoved) {
11692            if (checkComponentPermission(
11693                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
11694                    callingPid, callingUid, -1)
11695                    == PackageManager.PERMISSION_GRANTED) {
11696                if (uidRemoved) {
11697                    final Bundle intentExtras = intent.getExtras();
11698                    final int uid = intentExtras != null
11699                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
11700                    if (uid >= 0) {
11701                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
11702                        synchronized (bs) {
11703                            bs.removeUidStatsLocked(uid);
11704                        }
11705                    }
11706                } else {
11707                    Uri data = intent.getData();
11708                    String ssp;
11709                    if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11710                        if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
11711                            uninstallPackageLocked(ssp,
11712                                    intent.getIntExtra(Intent.EXTRA_UID, -1), false);
11713                            AttributeCache ac = AttributeCache.instance();
11714                            if (ac != null) {
11715                                ac.removePackage(ssp);
11716                            }
11717                        }
11718                    }
11719                }
11720            } else {
11721                String msg = "Permission Denial: " + intent.getAction()
11722                        + " broadcast from " + callerPackage + " (pid=" + callingPid
11723                        + ", uid=" + callingUid + ")"
11724                        + " requires "
11725                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
11726                Log.w(TAG, msg);
11727                throw new SecurityException(msg);
11728            }
11729        }
11730
11731        /*
11732         * If this is the time zone changed action, queue up a message that will reset the timezone
11733         * of all currently running processes. This message will get queued up before the broadcast
11734         * happens.
11735         */
11736        if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
11737            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
11738        }
11739
11740        /*
11741         * Prevent non-system code (defined here to be non-persistent
11742         * processes) from sending protected broadcasts.
11743         */
11744        if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID
11745                || callingUid == Process.SHELL_UID || callingUid == 0) {
11746            // Always okay.
11747        } else if (callerApp == null || !callerApp.persistent) {
11748            try {
11749                if (ActivityThread.getPackageManager().isProtectedBroadcast(
11750                        intent.getAction())) {
11751                    String msg = "Permission Denial: not allowed to send broadcast "
11752                            + intent.getAction() + " from pid="
11753                            + callingPid + ", uid=" + callingUid;
11754                    Log.w(TAG, msg);
11755                    throw new SecurityException(msg);
11756                }
11757            } catch (RemoteException e) {
11758                Log.w(TAG, "Remote exception", e);
11759                return BROADCAST_SUCCESS;
11760            }
11761        }
11762
11763        // Add to the sticky list if requested.
11764        if (sticky) {
11765            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
11766                    callingPid, callingUid)
11767                    != PackageManager.PERMISSION_GRANTED) {
11768                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
11769                        + callingPid + ", uid=" + callingUid
11770                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
11771                Log.w(TAG, msg);
11772                throw new SecurityException(msg);
11773            }
11774            if (requiredPermission != null) {
11775                Log.w(TAG, "Can't broadcast sticky intent " + intent
11776                        + " and enforce permission " + requiredPermission);
11777                return BROADCAST_STICKY_CANT_HAVE_PERMISSION;
11778            }
11779            if (intent.getComponent() != null) {
11780                throw new SecurityException(
11781                        "Sticky broadcasts can't target a specific component");
11782            }
11783            ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
11784            if (list == null) {
11785                list = new ArrayList<Intent>();
11786                mStickyBroadcasts.put(intent.getAction(), list);
11787            }
11788            int N = list.size();
11789            int i;
11790            for (i=0; i<N; i++) {
11791                if (intent.filterEquals(list.get(i))) {
11792                    // This sticky already exists, replace it.
11793                    list.set(i, new Intent(intent));
11794                    break;
11795                }
11796            }
11797            if (i >= N) {
11798                list.add(new Intent(intent));
11799            }
11800        }
11801
11802        // Figure out who all will receive this broadcast.
11803        List receivers = null;
11804        List<BroadcastFilter> registeredReceivers = null;
11805        try {
11806            if (intent.getComponent() != null) {
11807                // Broadcast is going to one specific receiver class...
11808                ActivityInfo ai = ActivityThread.getPackageManager().
11809                    getReceiverInfo(intent.getComponent(), STOCK_PM_FLAGS);
11810                if (ai != null) {
11811                    receivers = new ArrayList();
11812                    ResolveInfo ri = new ResolveInfo();
11813                    ri.activityInfo = ai;
11814                    receivers.add(ri);
11815                }
11816            } else {
11817                // Need to resolve the intent to interested receivers...
11818                if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
11819                         == 0) {
11820                    receivers =
11821                        ActivityThread.getPackageManager().queryIntentReceivers(
11822                                intent, resolvedType, STOCK_PM_FLAGS);
11823                }
11824                registeredReceivers = mReceiverResolver.queryIntent(intent, resolvedType, false);
11825            }
11826        } catch (RemoteException ex) {
11827            // pm is in same process, this will never happen.
11828        }
11829
11830        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
11831        if (!ordered && NR > 0) {
11832            // If we are not serializing this broadcast, then send the
11833            // registered receivers separately so they don't wait for the
11834            // components to be launched.
11835            BroadcastRecord r = new BroadcastRecord(intent, callerApp,
11836                    callerPackage, callingPid, callingUid, requiredPermission,
11837                    registeredReceivers, resultTo, resultCode, resultData, map,
11838                    ordered, false);
11839            if (DEBUG_BROADCAST) Log.v(
11840                    TAG, "Enqueueing parallel broadcast " + r
11841                    + ": prev had " + mParallelBroadcasts.size());
11842            mParallelBroadcasts.add(r);
11843            scheduleBroadcastsLocked();
11844            registeredReceivers = null;
11845            NR = 0;
11846        }
11847
11848        // Merge into one list.
11849        int ir = 0;
11850        if (receivers != null) {
11851            // A special case for PACKAGE_ADDED: do not allow the package
11852            // being added to see this broadcast.  This prevents them from
11853            // using this as a back door to get run as soon as they are
11854            // installed.  Maybe in the future we want to have a special install
11855            // broadcast or such for apps, but we'd like to deliberately make
11856            // this decision.
11857            boolean skip = false;
11858            if (intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
11859                skip = true;
11860            } else if (intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())) {
11861                skip = true;
11862            } else if (intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
11863                skip = true;
11864            }
11865            String skipPackage = (skip && intent.getData() != null)
11866                    ? intent.getData().getSchemeSpecificPart()
11867                    : null;
11868            if (skipPackage != null && receivers != null) {
11869                int NT = receivers.size();
11870                for (int it=0; it<NT; it++) {
11871                    ResolveInfo curt = (ResolveInfo)receivers.get(it);
11872                    if (curt.activityInfo.packageName.equals(skipPackage)) {
11873                        receivers.remove(it);
11874                        it--;
11875                        NT--;
11876                    }
11877                }
11878            }
11879
11880            int NT = receivers != null ? receivers.size() : 0;
11881            int it = 0;
11882            ResolveInfo curt = null;
11883            BroadcastFilter curr = null;
11884            while (it < NT && ir < NR) {
11885                if (curt == null) {
11886                    curt = (ResolveInfo)receivers.get(it);
11887                }
11888                if (curr == null) {
11889                    curr = registeredReceivers.get(ir);
11890                }
11891                if (curr.getPriority() >= curt.priority) {
11892                    // Insert this broadcast record into the final list.
11893                    receivers.add(it, curr);
11894                    ir++;
11895                    curr = null;
11896                    it++;
11897                    NT++;
11898                } else {
11899                    // Skip to the next ResolveInfo in the final list.
11900                    it++;
11901                    curt = null;
11902                }
11903            }
11904        }
11905        while (ir < NR) {
11906            if (receivers == null) {
11907                receivers = new ArrayList();
11908            }
11909            receivers.add(registeredReceivers.get(ir));
11910            ir++;
11911        }
11912
11913        if ((receivers != null && receivers.size() > 0)
11914                || resultTo != null) {
11915            BroadcastRecord r = new BroadcastRecord(intent, callerApp,
11916                    callerPackage, callingPid, callingUid, requiredPermission,
11917                    receivers, resultTo, resultCode, resultData, map, ordered, false);
11918            if (DEBUG_BROADCAST) Log.v(
11919                    TAG, "Enqueueing ordered broadcast " + r
11920                    + ": prev had " + mOrderedBroadcasts.size());
11921            if (DEBUG_BROADCAST) {
11922                int seq = r.intent.getIntExtra("seq", -1);
11923                Log.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
11924            }
11925            mOrderedBroadcasts.add(r);
11926            scheduleBroadcastsLocked();
11927        }
11928
11929        return BROADCAST_SUCCESS;
11930    }
11931
11932    public final int broadcastIntent(IApplicationThread caller,
11933            Intent intent, String resolvedType, IIntentReceiver resultTo,
11934            int resultCode, String resultData, Bundle map,
11935            String requiredPermission, boolean serialized, boolean sticky) {
11936        // Refuse possible leaked file descriptors
11937        if (intent != null && intent.hasFileDescriptors() == true) {
11938            throw new IllegalArgumentException("File descriptors passed in Intent");
11939        }
11940
11941        synchronized(this) {
11942            int flags = intent.getFlags();
11943
11944            if (!mSystemReady) {
11945                // if the caller really truly claims to know what they're doing, go
11946                // ahead and allow the broadcast without launching any receivers
11947                if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
11948                    intent = new Intent(intent);
11949                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11950                } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0){
11951                    Log.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
11952                            + " before boot completion");
11953                    throw new IllegalStateException("Cannot broadcast before boot completed");
11954                }
11955            }
11956
11957            if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
11958                throw new IllegalArgumentException(
11959                        "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
11960            }
11961
11962            final ProcessRecord callerApp = getRecordForAppLocked(caller);
11963            final int callingPid = Binder.getCallingPid();
11964            final int callingUid = Binder.getCallingUid();
11965            final long origId = Binder.clearCallingIdentity();
11966            int res = broadcastIntentLocked(callerApp,
11967                    callerApp != null ? callerApp.info.packageName : null,
11968                    intent, resolvedType, resultTo,
11969                    resultCode, resultData, map, requiredPermission, serialized,
11970                    sticky, callingPid, callingUid);
11971            Binder.restoreCallingIdentity(origId);
11972            return res;
11973        }
11974    }
11975
11976    int broadcastIntentInPackage(String packageName, int uid,
11977            Intent intent, String resolvedType, IIntentReceiver resultTo,
11978            int resultCode, String resultData, Bundle map,
11979            String requiredPermission, boolean serialized, boolean sticky) {
11980        synchronized(this) {
11981            final long origId = Binder.clearCallingIdentity();
11982            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
11983                    resultTo, resultCode, resultData, map, requiredPermission,
11984                    serialized, sticky, -1, uid);
11985            Binder.restoreCallingIdentity(origId);
11986            return res;
11987        }
11988    }
11989
11990    public final void unbroadcastIntent(IApplicationThread caller,
11991            Intent intent) {
11992        // Refuse possible leaked file descriptors
11993        if (intent != null && intent.hasFileDescriptors() == true) {
11994            throw new IllegalArgumentException("File descriptors passed in Intent");
11995        }
11996
11997        synchronized(this) {
11998            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
11999                    != PackageManager.PERMISSION_GRANTED) {
12000                String msg = "Permission Denial: unbroadcastIntent() from pid="
12001                        + Binder.getCallingPid()
12002                        + ", uid=" + Binder.getCallingUid()
12003                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
12004                Log.w(TAG, msg);
12005                throw new SecurityException(msg);
12006            }
12007            ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
12008            if (list != null) {
12009                int N = list.size();
12010                int i;
12011                for (i=0; i<N; i++) {
12012                    if (intent.filterEquals(list.get(i))) {
12013                        list.remove(i);
12014                        break;
12015                    }
12016                }
12017            }
12018        }
12019    }
12020
12021    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
12022            String resultData, Bundle resultExtras, boolean resultAbort,
12023            boolean explicit) {
12024        if (mOrderedBroadcasts.size() == 0) {
12025            if (explicit) {
12026                Log.w(TAG, "finishReceiver called but no pending broadcasts");
12027            }
12028            return false;
12029        }
12030        BroadcastRecord r = mOrderedBroadcasts.get(0);
12031        if (r.receiver == null) {
12032            if (explicit) {
12033                Log.w(TAG, "finishReceiver called but none active");
12034            }
12035            return false;
12036        }
12037        if (r.receiver != receiver) {
12038            Log.w(TAG, "finishReceiver called but active receiver is different");
12039            return false;
12040        }
12041        int state = r.state;
12042        r.state = r.IDLE;
12043        if (state == r.IDLE) {
12044            if (explicit) {
12045                Log.w(TAG, "finishReceiver called but state is IDLE");
12046            }
12047        }
12048        r.receiver = null;
12049        r.intent.setComponent(null);
12050        if (r.curApp != null) {
12051            r.curApp.curReceiver = null;
12052        }
12053        if (r.curFilter != null) {
12054            r.curFilter.receiverList.curBroadcast = null;
12055        }
12056        r.curFilter = null;
12057        r.curApp = null;
12058        r.curComponent = null;
12059        r.curReceiver = null;
12060        mPendingBroadcast = null;
12061
12062        r.resultCode = resultCode;
12063        r.resultData = resultData;
12064        r.resultExtras = resultExtras;
12065        r.resultAbort = resultAbort;
12066
12067        // We will process the next receiver right now if this is finishing
12068        // an app receiver (which is always asynchronous) or after we have
12069        // come back from calling a receiver.
12070        return state == BroadcastRecord.APP_RECEIVE
12071                || state == BroadcastRecord.CALL_DONE_RECEIVE;
12072    }
12073
12074    public void finishReceiver(IBinder who, int resultCode, String resultData,
12075            Bundle resultExtras, boolean resultAbort) {
12076        if (DEBUG_BROADCAST) Log.v(TAG, "Finish receiver: " + who);
12077
12078        // Refuse possible leaked file descriptors
12079        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
12080            throw new IllegalArgumentException("File descriptors passed in Bundle");
12081        }
12082
12083        boolean doNext;
12084
12085        final long origId = Binder.clearCallingIdentity();
12086
12087        synchronized(this) {
12088            doNext = finishReceiverLocked(
12089                who, resultCode, resultData, resultExtras, resultAbort, true);
12090        }
12091
12092        if (doNext) {
12093            processNextBroadcast(false);
12094        }
12095        trimApplications();
12096
12097        Binder.restoreCallingIdentity(origId);
12098    }
12099
12100    private final void logBroadcastReceiverDiscard(BroadcastRecord r) {
12101        if (r.nextReceiver > 0) {
12102            Object curReceiver = r.receivers.get(r.nextReceiver-1);
12103            if (curReceiver instanceof BroadcastFilter) {
12104                BroadcastFilter bf = (BroadcastFilter) curReceiver;
12105                EventLog.writeEvent(LOG_AM_BROADCAST_DISCARD_FILTER,
12106                        System.identityHashCode(r),
12107                        r.intent.getAction(),
12108                        r.nextReceiver - 1,
12109                        System.identityHashCode(bf));
12110            } else {
12111                EventLog.writeEvent(LOG_AM_BROADCAST_DISCARD_APP,
12112                        System.identityHashCode(r),
12113                        r.intent.getAction(),
12114                        r.nextReceiver - 1,
12115                        ((ResolveInfo)curReceiver).toString());
12116            }
12117        } else {
12118            Log.w(TAG, "Discarding broadcast before first receiver is invoked: "
12119                    + r);
12120            EventLog.writeEvent(LOG_AM_BROADCAST_DISCARD_APP,
12121                    System.identityHashCode(r),
12122                    r.intent.getAction(),
12123                    r.nextReceiver,
12124                    "NONE");
12125        }
12126    }
12127
12128    private final void broadcastTimeout() {
12129        synchronized (this) {
12130            if (mOrderedBroadcasts.size() == 0) {
12131                return;
12132            }
12133            long now = SystemClock.uptimeMillis();
12134            BroadcastRecord r = mOrderedBroadcasts.get(0);
12135            if ((r.startTime+BROADCAST_TIMEOUT) > now) {
12136                if (DEBUG_BROADCAST) Log.v(TAG,
12137                        "Premature timeout @ " + now + ": resetting BROADCAST_TIMEOUT_MSG for "
12138                        + (r.startTime + BROADCAST_TIMEOUT));
12139                Message msg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG);
12140                mHandler.sendMessageAtTime(msg, r.startTime+BROADCAST_TIMEOUT);
12141                return;
12142            }
12143
12144            Log.w(TAG, "Timeout of broadcast " + r + " - receiver=" + r.receiver);
12145            r.startTime = now;
12146            r.anrCount++;
12147
12148            // Current receiver has passed its expiration date.
12149            if (r.nextReceiver <= 0) {
12150                Log.w(TAG, "Timeout on receiver with nextReceiver <= 0");
12151                return;
12152            }
12153
12154            ProcessRecord app = null;
12155
12156            Object curReceiver = r.receivers.get(r.nextReceiver-1);
12157            Log.w(TAG, "Receiver during timeout: " + curReceiver);
12158            logBroadcastReceiverDiscard(r);
12159            if (curReceiver instanceof BroadcastFilter) {
12160                BroadcastFilter bf = (BroadcastFilter)curReceiver;
12161                if (bf.receiverList.pid != 0
12162                        && bf.receiverList.pid != MY_PID) {
12163                    synchronized (this.mPidsSelfLocked) {
12164                        app = this.mPidsSelfLocked.get(
12165                                bf.receiverList.pid);
12166                    }
12167                }
12168            } else {
12169                app = r.curApp;
12170            }
12171
12172            if (app != null) {
12173                appNotRespondingLocked(app, null, null,
12174                        "Broadcast of " + r.intent.toString());
12175            }
12176
12177            if (mPendingBroadcast == r) {
12178                mPendingBroadcast = null;
12179            }
12180
12181            // Move on to the next receiver.
12182            finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
12183                    r.resultExtras, r.resultAbort, true);
12184            scheduleBroadcastsLocked();
12185        }
12186    }
12187
12188    private final void processCurBroadcastLocked(BroadcastRecord r,
12189            ProcessRecord app) throws RemoteException {
12190        if (app.thread == null) {
12191            throw new RemoteException();
12192        }
12193        r.receiver = app.thread.asBinder();
12194        r.curApp = app;
12195        app.curReceiver = r;
12196        updateLRUListLocked(app, true);
12197
12198        // Tell the application to launch this receiver.
12199        r.intent.setComponent(r.curComponent);
12200
12201        boolean started = false;
12202        try {
12203            if (DEBUG_BROADCAST_LIGHT) Log.v(TAG,
12204                    "Delivering to component " + r.curComponent
12205                    + ": " + r);
12206            ensurePackageDexOpt(r.intent.getComponent().getPackageName());
12207            app.thread.scheduleReceiver(new Intent(r.intent), r.curReceiver,
12208                    r.resultCode, r.resultData, r.resultExtras, r.ordered);
12209            started = true;
12210        } finally {
12211            if (!started) {
12212                r.receiver = null;
12213                r.curApp = null;
12214                app.curReceiver = null;
12215            }
12216        }
12217
12218    }
12219
12220    static void performReceive(ProcessRecord app, IIntentReceiver receiver,
12221            Intent intent, int resultCode, String data, Bundle extras,
12222            boolean ordered, boolean sticky) throws RemoteException {
12223        if (app != null && app.thread != null) {
12224            // If we have an app thread, do the call through that so it is
12225            // correctly ordered with other one-way calls.
12226            app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
12227                    data, extras, ordered, sticky);
12228        } else {
12229            receiver.performReceive(intent, resultCode, data, extras, ordered, sticky);
12230        }
12231    }
12232
12233    private final void deliverToRegisteredReceiver(BroadcastRecord r,
12234            BroadcastFilter filter, boolean ordered) {
12235        boolean skip = false;
12236        if (filter.requiredPermission != null) {
12237            int perm = checkComponentPermission(filter.requiredPermission,
12238                    r.callingPid, r.callingUid, -1);
12239            if (perm != PackageManager.PERMISSION_GRANTED) {
12240                Log.w(TAG, "Permission Denial: broadcasting "
12241                        + r.intent.toString()
12242                        + " from " + r.callerPackage + " (pid="
12243                        + r.callingPid + ", uid=" + r.callingUid + ")"
12244                        + " requires " + filter.requiredPermission
12245                        + " due to registered receiver " + filter);
12246                skip = true;
12247            }
12248        }
12249        if (r.requiredPermission != null) {
12250            int perm = checkComponentPermission(r.requiredPermission,
12251                    filter.receiverList.pid, filter.receiverList.uid, -1);
12252            if (perm != PackageManager.PERMISSION_GRANTED) {
12253                Log.w(TAG, "Permission Denial: receiving "
12254                        + r.intent.toString()
12255                        + " to " + filter.receiverList.app
12256                        + " (pid=" + filter.receiverList.pid
12257                        + ", uid=" + filter.receiverList.uid + ")"
12258                        + " requires " + r.requiredPermission
12259                        + " due to sender " + r.callerPackage
12260                        + " (uid " + r.callingUid + ")");
12261                skip = true;
12262            }
12263        }
12264
12265        if (!skip) {
12266            // If this is not being sent as an ordered broadcast, then we
12267            // don't want to touch the fields that keep track of the current
12268            // state of ordered broadcasts.
12269            if (ordered) {
12270                r.receiver = filter.receiverList.receiver.asBinder();
12271                r.curFilter = filter;
12272                filter.receiverList.curBroadcast = r;
12273                r.state = BroadcastRecord.CALL_IN_RECEIVE;
12274                if (filter.receiverList.app != null) {
12275                    // Bump hosting application to no longer be in background
12276                    // scheduling class.  Note that we can't do that if there
12277                    // isn't an app...  but we can only be in that case for
12278                    // things that directly call the IActivityManager API, which
12279                    // are already core system stuff so don't matter for this.
12280                    r.curApp = filter.receiverList.app;
12281                    filter.receiverList.app.curReceiver = r;
12282                    updateOomAdjLocked();
12283                }
12284            }
12285            try {
12286                if (DEBUG_BROADCAST_LIGHT) {
12287                    int seq = r.intent.getIntExtra("seq", -1);
12288                    Log.i(TAG, "Delivering to " + filter.receiverList.app
12289                            + " (seq=" + seq + "): " + r);
12290                }
12291                performReceive(filter.receiverList.app, filter.receiverList.receiver,
12292                    new Intent(r.intent), r.resultCode,
12293                    r.resultData, r.resultExtras, r.ordered, r.sticky);
12294                if (ordered) {
12295                    r.state = BroadcastRecord.CALL_DONE_RECEIVE;
12296                }
12297            } catch (RemoteException e) {
12298                Log.w(TAG, "Failure sending broadcast " + r.intent, e);
12299                if (ordered) {
12300                    r.receiver = null;
12301                    r.curFilter = null;
12302                    filter.receiverList.curBroadcast = null;
12303                    if (filter.receiverList.app != null) {
12304                        filter.receiverList.app.curReceiver = null;
12305                    }
12306                }
12307            }
12308        }
12309    }
12310
12311    private final void processNextBroadcast(boolean fromMsg) {
12312        synchronized(this) {
12313            BroadcastRecord r;
12314
12315            if (DEBUG_BROADCAST) Log.v(TAG, "processNextBroadcast: "
12316                    + mParallelBroadcasts.size() + " broadcasts, "
12317                    + mOrderedBroadcasts.size() + " serialized broadcasts");
12318
12319            updateCpuStats();
12320
12321            if (fromMsg) {
12322                mBroadcastsScheduled = false;
12323            }
12324
12325            // First, deliver any non-serialized broadcasts right away.
12326            while (mParallelBroadcasts.size() > 0) {
12327                r = mParallelBroadcasts.remove(0);
12328                final int N = r.receivers.size();
12329                if (DEBUG_BROADCAST_LIGHT) Log.v(TAG, "Processing parallel broadcast "
12330                        + r);
12331                for (int i=0; i<N; i++) {
12332                    Object target = r.receivers.get(i);
12333                    if (DEBUG_BROADCAST)  Log.v(TAG,
12334                            "Delivering non-serialized to registered "
12335                            + target + ": " + r);
12336                    deliverToRegisteredReceiver(r, (BroadcastFilter)target, false);
12337                }
12338                if (DEBUG_BROADCAST_LIGHT) Log.v(TAG, "Done with parallel broadcast "
12339                        + r);
12340            }
12341
12342            // Now take care of the next serialized one...
12343
12344            // If we are waiting for a process to come up to handle the next
12345            // broadcast, then do nothing at this point.  Just in case, we
12346            // check that the process we're waiting for still exists.
12347            if (mPendingBroadcast != null) {
12348                if (DEBUG_BROADCAST_LIGHT) {
12349                    Log.v(TAG, "processNextBroadcast: waiting for "
12350                            + mPendingBroadcast.curApp);
12351                }
12352
12353                boolean isDead;
12354                synchronized (mPidsSelfLocked) {
12355                    isDead = (mPidsSelfLocked.get(mPendingBroadcast.curApp.pid) == null);
12356                }
12357                if (!isDead) {
12358                    // It's still alive, so keep waiting
12359                    return;
12360                } else {
12361                    Log.w(TAG, "pending app " + mPendingBroadcast.curApp
12362                            + " died before responding to broadcast");
12363                    mPendingBroadcast = null;
12364                }
12365            }
12366
12367            boolean looped = false;
12368
12369            do {
12370                if (mOrderedBroadcasts.size() == 0) {
12371                    // No more broadcasts pending, so all done!
12372                    scheduleAppGcsLocked();
12373                    if (looped) {
12374                        // If we had finished the last ordered broadcast, then
12375                        // make sure all processes have correct oom and sched
12376                        // adjustments.
12377                        updateOomAdjLocked();
12378                    }
12379                    return;
12380                }
12381                r = mOrderedBroadcasts.get(0);
12382                boolean forceReceive = false;
12383
12384                // Ensure that even if something goes awry with the timeout
12385                // detection, we catch "hung" broadcasts here, discard them,
12386                // and continue to make progress.
12387                int numReceivers = (r.receivers != null) ? r.receivers.size() : 0;
12388                long now = SystemClock.uptimeMillis();
12389                if (r.dispatchTime > 0) {
12390                    if ((numReceivers > 0) &&
12391                            (now > r.dispatchTime + (2*BROADCAST_TIMEOUT*numReceivers))) {
12392                        Log.w(TAG, "Hung broadcast discarded after timeout failure:"
12393                                + " now=" + now
12394                                + " dispatchTime=" + r.dispatchTime
12395                                + " startTime=" + r.startTime
12396                                + " intent=" + r.intent
12397                                + " numReceivers=" + numReceivers
12398                                + " nextReceiver=" + r.nextReceiver
12399                                + " state=" + r.state);
12400                        broadcastTimeout(); // forcibly finish this broadcast
12401                        forceReceive = true;
12402                        r.state = BroadcastRecord.IDLE;
12403                    }
12404                }
12405
12406                if (r.state != BroadcastRecord.IDLE) {
12407                    if (DEBUG_BROADCAST) Log.d(TAG,
12408                            "processNextBroadcast() called when not idle (state="
12409                            + r.state + ")");
12410                    return;
12411                }
12412
12413                if (r.receivers == null || r.nextReceiver >= numReceivers
12414                        || r.resultAbort || forceReceive) {
12415                    // No more receivers for this broadcast!  Send the final
12416                    // result if requested...
12417                    if (r.resultTo != null) {
12418                        try {
12419                            if (DEBUG_BROADCAST) {
12420                                int seq = r.intent.getIntExtra("seq", -1);
12421                                Log.i(TAG, "Finishing broadcast " + r.intent.getAction()
12422                                        + " seq=" + seq + " app=" + r.callerApp);
12423                            }
12424                            performReceive(r.callerApp, r.resultTo,
12425                                new Intent(r.intent), r.resultCode,
12426                                r.resultData, r.resultExtras, false, false);
12427                        } catch (RemoteException e) {
12428                            Log.w(TAG, "Failure sending broadcast result of " + r.intent, e);
12429                        }
12430                    }
12431
12432                    if (DEBUG_BROADCAST) Log.v(TAG, "Cancelling BROADCAST_TIMEOUT_MSG");
12433                    mHandler.removeMessages(BROADCAST_TIMEOUT_MSG);
12434
12435                    if (DEBUG_BROADCAST_LIGHT) Log.v(TAG, "Finished with ordered broadcast "
12436                            + r);
12437
12438                    // ... and on to the next...
12439                    mOrderedBroadcasts.remove(0);
12440                    r = null;
12441                    looped = true;
12442                    continue;
12443                }
12444            } while (r == null);
12445
12446            // Get the next receiver...
12447            int recIdx = r.nextReceiver++;
12448
12449            // Keep track of when this receiver started, and make sure there
12450            // is a timeout message pending to kill it if need be.
12451            r.startTime = SystemClock.uptimeMillis();
12452            if (recIdx == 0) {
12453                r.dispatchTime = r.startTime;
12454
12455                if (DEBUG_BROADCAST_LIGHT) Log.v(TAG, "Processing ordered broadcast "
12456                        + r);
12457                if (DEBUG_BROADCAST) Log.v(TAG,
12458                        "Submitting BROADCAST_TIMEOUT_MSG for "
12459                        + (r.startTime + BROADCAST_TIMEOUT));
12460                Message msg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG);
12461                mHandler.sendMessageAtTime(msg, r.startTime+BROADCAST_TIMEOUT);
12462            }
12463
12464            Object nextReceiver = r.receivers.get(recIdx);
12465            if (nextReceiver instanceof BroadcastFilter) {
12466                // Simple case: this is a registered receiver who gets
12467                // a direct call.
12468                BroadcastFilter filter = (BroadcastFilter)nextReceiver;
12469                if (DEBUG_BROADCAST)  Log.v(TAG,
12470                        "Delivering serialized to registered "
12471                        + filter + ": " + r);
12472                deliverToRegisteredReceiver(r, filter, r.ordered);
12473                if (r.receiver == null || !r.ordered) {
12474                    // The receiver has already finished, so schedule to
12475                    // process the next one.
12476                    r.state = BroadcastRecord.IDLE;
12477                    scheduleBroadcastsLocked();
12478                }
12479                return;
12480            }
12481
12482            // Hard case: need to instantiate the receiver, possibly
12483            // starting its application process to host it.
12484
12485            ResolveInfo info =
12486                (ResolveInfo)nextReceiver;
12487
12488            boolean skip = false;
12489            int perm = checkComponentPermission(info.activityInfo.permission,
12490                    r.callingPid, r.callingUid,
12491                    info.activityInfo.exported
12492                            ? -1 : info.activityInfo.applicationInfo.uid);
12493            if (perm != PackageManager.PERMISSION_GRANTED) {
12494                Log.w(TAG, "Permission Denial: broadcasting "
12495                        + r.intent.toString()
12496                        + " from " + r.callerPackage + " (pid=" + r.callingPid
12497                        + ", uid=" + r.callingUid + ")"
12498                        + " requires " + info.activityInfo.permission
12499                        + " due to receiver " + info.activityInfo.packageName
12500                        + "/" + info.activityInfo.name);
12501                skip = true;
12502            }
12503            if (r.callingUid != Process.SYSTEM_UID &&
12504                r.requiredPermission != null) {
12505                try {
12506                    perm = ActivityThread.getPackageManager().
12507                            checkPermission(r.requiredPermission,
12508                                    info.activityInfo.applicationInfo.packageName);
12509                } catch (RemoteException e) {
12510                    perm = PackageManager.PERMISSION_DENIED;
12511                }
12512                if (perm != PackageManager.PERMISSION_GRANTED) {
12513                    Log.w(TAG, "Permission Denial: receiving "
12514                            + r.intent + " to "
12515                            + info.activityInfo.applicationInfo.packageName
12516                            + " requires " + r.requiredPermission
12517                            + " due to sender " + r.callerPackage
12518                            + " (uid " + r.callingUid + ")");
12519                    skip = true;
12520                }
12521            }
12522            if (r.curApp != null && r.curApp.crashing) {
12523                // If the target process is crashing, just skip it.
12524                skip = true;
12525            }
12526
12527            if (skip) {
12528                r.receiver = null;
12529                r.curFilter = null;
12530                r.state = BroadcastRecord.IDLE;
12531                scheduleBroadcastsLocked();
12532                return;
12533            }
12534
12535            r.state = BroadcastRecord.APP_RECEIVE;
12536            String targetProcess = info.activityInfo.processName;
12537            r.curComponent = new ComponentName(
12538                    info.activityInfo.applicationInfo.packageName,
12539                    info.activityInfo.name);
12540            r.curReceiver = info.activityInfo;
12541
12542            // Is this receiver's application already running?
12543            ProcessRecord app = getProcessRecordLocked(targetProcess,
12544                    info.activityInfo.applicationInfo.uid);
12545            if (app != null && app.thread != null) {
12546                try {
12547                    processCurBroadcastLocked(r, app);
12548                    return;
12549                } catch (RemoteException e) {
12550                    Log.w(TAG, "Exception when sending broadcast to "
12551                          + r.curComponent, e);
12552                }
12553
12554                // If a dead object exception was thrown -- fall through to
12555                // restart the application.
12556            }
12557
12558            // Not running -- get it started, to be executed when the app comes up.
12559            if ((r.curApp=startProcessLocked(targetProcess,
12560                    info.activityInfo.applicationInfo, true,
12561                    r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND,
12562                    "broadcast", r.curComponent,
12563                    (r.intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0))
12564                            == null) {
12565                // Ah, this recipient is unavailable.  Finish it if necessary,
12566                // and mark the broadcast record as ready for the next.
12567                Log.w(TAG, "Unable to launch app "
12568                        + info.activityInfo.applicationInfo.packageName + "/"
12569                        + info.activityInfo.applicationInfo.uid + " for broadcast "
12570                        + r.intent + ": process is bad");
12571                logBroadcastReceiverDiscard(r);
12572                finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
12573                        r.resultExtras, r.resultAbort, true);
12574                scheduleBroadcastsLocked();
12575                r.state = BroadcastRecord.IDLE;
12576                return;
12577            }
12578
12579            mPendingBroadcast = r;
12580        }
12581    }
12582
12583    // =========================================================
12584    // INSTRUMENTATION
12585    // =========================================================
12586
12587    public boolean startInstrumentation(ComponentName className,
12588            String profileFile, int flags, Bundle arguments,
12589            IInstrumentationWatcher watcher) {
12590        // Refuse possible leaked file descriptors
12591        if (arguments != null && arguments.hasFileDescriptors()) {
12592            throw new IllegalArgumentException("File descriptors passed in Bundle");
12593        }
12594
12595        synchronized(this) {
12596            InstrumentationInfo ii = null;
12597            ApplicationInfo ai = null;
12598            try {
12599                ii = mContext.getPackageManager().getInstrumentationInfo(
12600                    className, STOCK_PM_FLAGS);
12601                ai = mContext.getPackageManager().getApplicationInfo(
12602                    ii.targetPackage, STOCK_PM_FLAGS);
12603            } catch (PackageManager.NameNotFoundException e) {
12604            }
12605            if (ii == null) {
12606                reportStartInstrumentationFailure(watcher, className,
12607                        "Unable to find instrumentation info for: " + className);
12608                return false;
12609            }
12610            if (ai == null) {
12611                reportStartInstrumentationFailure(watcher, className,
12612                        "Unable to find instrumentation target package: " + ii.targetPackage);
12613                return false;
12614            }
12615
12616            int match = mContext.getPackageManager().checkSignatures(
12617                    ii.targetPackage, ii.packageName);
12618            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
12619                String msg = "Permission Denial: starting instrumentation "
12620                        + className + " from pid="
12621                        + Binder.getCallingPid()
12622                        + ", uid=" + Binder.getCallingPid()
12623                        + " not allowed because package " + ii.packageName
12624                        + " does not have a signature matching the target "
12625                        + ii.targetPackage;
12626                reportStartInstrumentationFailure(watcher, className, msg);
12627                throw new SecurityException(msg);
12628            }
12629
12630            final long origId = Binder.clearCallingIdentity();
12631            uninstallPackageLocked(ii.targetPackage, -1, true);
12632            ProcessRecord app = addAppLocked(ai);
12633            app.instrumentationClass = className;
12634            app.instrumentationInfo = ai;
12635            app.instrumentationProfileFile = profileFile;
12636            app.instrumentationArguments = arguments;
12637            app.instrumentationWatcher = watcher;
12638            app.instrumentationResultClass = className;
12639            Binder.restoreCallingIdentity(origId);
12640        }
12641
12642        return true;
12643    }
12644
12645    /**
12646     * Report errors that occur while attempting to start Instrumentation.  Always writes the
12647     * error to the logs, but if somebody is watching, send the report there too.  This enables
12648     * the "am" command to report errors with more information.
12649     *
12650     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
12651     * @param cn The component name of the instrumentation.
12652     * @param report The error report.
12653     */
12654    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
12655            ComponentName cn, String report) {
12656        Log.w(TAG, report);
12657        try {
12658            if (watcher != null) {
12659                Bundle results = new Bundle();
12660                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
12661                results.putString("Error", report);
12662                watcher.instrumentationStatus(cn, -1, results);
12663            }
12664        } catch (RemoteException e) {
12665            Log.w(TAG, e);
12666        }
12667    }
12668
12669    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
12670        if (app.instrumentationWatcher != null) {
12671            try {
12672                // NOTE:  IInstrumentationWatcher *must* be oneway here
12673                app.instrumentationWatcher.instrumentationFinished(
12674                    app.instrumentationClass,
12675                    resultCode,
12676                    results);
12677            } catch (RemoteException e) {
12678            }
12679        }
12680        app.instrumentationWatcher = null;
12681        app.instrumentationClass = null;
12682        app.instrumentationInfo = null;
12683        app.instrumentationProfileFile = null;
12684        app.instrumentationArguments = null;
12685
12686        uninstallPackageLocked(app.processName, -1, false);
12687    }
12688
12689    public void finishInstrumentation(IApplicationThread target,
12690            int resultCode, Bundle results) {
12691        // Refuse possible leaked file descriptors
12692        if (results != null && results.hasFileDescriptors()) {
12693            throw new IllegalArgumentException("File descriptors passed in Intent");
12694        }
12695
12696        synchronized(this) {
12697            ProcessRecord app = getRecordForAppLocked(target);
12698            if (app == null) {
12699                Log.w(TAG, "finishInstrumentation: no app for " + target);
12700                return;
12701            }
12702            final long origId = Binder.clearCallingIdentity();
12703            finishInstrumentationLocked(app, resultCode, results);
12704            Binder.restoreCallingIdentity(origId);
12705        }
12706    }
12707
12708    // =========================================================
12709    // CONFIGURATION
12710    // =========================================================
12711
12712    public ConfigurationInfo getDeviceConfigurationInfo() {
12713        ConfigurationInfo config = new ConfigurationInfo();
12714        synchronized (this) {
12715            config.reqTouchScreen = mConfiguration.touchscreen;
12716            config.reqKeyboardType = mConfiguration.keyboard;
12717            config.reqNavigation = mConfiguration.navigation;
12718            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
12719                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
12720                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
12721            }
12722            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
12723                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
12724                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
12725            }
12726            config.reqGlEsVersion = GL_ES_VERSION;
12727        }
12728        return config;
12729    }
12730
12731    public Configuration getConfiguration() {
12732        Configuration ci;
12733        synchronized(this) {
12734            ci = new Configuration(mConfiguration);
12735        }
12736        return ci;
12737    }
12738
12739    public void updateConfiguration(Configuration values) {
12740        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
12741                "updateConfiguration()");
12742
12743        synchronized(this) {
12744            if (values == null && mWindowManager != null) {
12745                // sentinel: fetch the current configuration from the window manager
12746                values = mWindowManager.computeNewConfiguration();
12747            }
12748
12749            final long origId = Binder.clearCallingIdentity();
12750            updateConfigurationLocked(values, null);
12751            Binder.restoreCallingIdentity(origId);
12752        }
12753    }
12754
12755    /**
12756     * Do either or both things: (1) change the current configuration, and (2)
12757     * make sure the given activity is running with the (now) current
12758     * configuration.  Returns true if the activity has been left running, or
12759     * false if <var>starting</var> is being destroyed to match the new
12760     * configuration.
12761     */
12762    public boolean updateConfigurationLocked(Configuration values,
12763            HistoryRecord starting) {
12764        int changes = 0;
12765
12766        boolean kept = true;
12767
12768        if (values != null) {
12769            Configuration newConfig = new Configuration(mConfiguration);
12770            changes = newConfig.updateFrom(values);
12771            if (changes != 0) {
12772                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
12773                    Log.i(TAG, "Updating configuration to: " + values);
12774                }
12775
12776                EventLog.writeEvent(LOG_CONFIGURATION_CHANGED, changes);
12777
12778                if (values.locale != null) {
12779                    saveLocaleLocked(values.locale,
12780                                     !values.locale.equals(mConfiguration.locale),
12781                                     values.userSetLocale);
12782                }
12783
12784                mConfiguration = newConfig;
12785                Log.i(TAG, "Config changed: " + newConfig);
12786
12787                Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
12788                msg.obj = new Configuration(mConfiguration);
12789                mHandler.sendMessage(msg);
12790
12791                final int N = mLRUProcesses.size();
12792                for (int i=0; i<N; i++) {
12793                    ProcessRecord app = mLRUProcesses.get(i);
12794                    try {
12795                        if (app.thread != null) {
12796                            if (DEBUG_CONFIGURATION) Log.v(TAG, "Sending to proc "
12797                                    + app.processName + " new config " + mConfiguration);
12798                            app.thread.scheduleConfigurationChanged(mConfiguration);
12799                        }
12800                    } catch (Exception e) {
12801                    }
12802                }
12803                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
12804                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
12805                        null, false, false, MY_PID, Process.SYSTEM_UID);
12806
12807                AttributeCache ac = AttributeCache.instance();
12808                if (ac != null) {
12809                    ac.updateConfiguration(mConfiguration);
12810                }
12811            }
12812        }
12813
12814        if (changes != 0 && starting == null) {
12815            // If the configuration changed, and the caller is not already
12816            // in the process of starting an activity, then find the top
12817            // activity to check if its configuration needs to change.
12818            starting = topRunningActivityLocked(null);
12819        }
12820
12821        if (starting != null) {
12822            kept = ensureActivityConfigurationLocked(starting, changes);
12823            if (kept) {
12824                // If this didn't result in the starting activity being
12825                // destroyed, then we need to make sure at this point that all
12826                // other activities are made visible.
12827                if (DEBUG_SWITCH) Log.i(TAG, "Config didn't destroy " + starting
12828                        + ", ensuring others are correct.");
12829                ensureActivitiesVisibleLocked(starting, changes);
12830            }
12831        }
12832
12833        return kept;
12834    }
12835
12836    private final boolean relaunchActivityLocked(HistoryRecord r,
12837            int changes, boolean andResume) {
12838        List<ResultInfo> results = null;
12839        List<Intent> newIntents = null;
12840        if (andResume) {
12841            results = r.results;
12842            newIntents = r.newIntents;
12843        }
12844        if (DEBUG_SWITCH) Log.v(TAG, "Relaunching: " + r
12845                + " with results=" + results + " newIntents=" + newIntents
12846                + " andResume=" + andResume);
12847        EventLog.writeEvent(andResume ? LOG_AM_RELAUNCH_RESUME_ACTIVITY
12848                : LOG_AM_RELAUNCH_ACTIVITY, System.identityHashCode(r),
12849                r.task.taskId, r.shortComponentName);
12850
12851        r.startFreezingScreenLocked(r.app, 0);
12852
12853        try {
12854            if (DEBUG_SWITCH) Log.i(TAG, "Switch is restarting resumed " + r);
12855            r.app.thread.scheduleRelaunchActivity(r, results, newIntents,
12856                    changes, !andResume);
12857            // Note: don't need to call pauseIfSleepingLocked() here, because
12858            // the caller will only pass in 'andResume' if this activity is
12859            // currently resumed, which implies we aren't sleeping.
12860        } catch (RemoteException e) {
12861            return false;
12862        }
12863
12864        if (andResume) {
12865            r.results = null;
12866            r.newIntents = null;
12867            reportResumedActivityLocked(r);
12868        }
12869
12870        return true;
12871    }
12872
12873    /**
12874     * Make sure the given activity matches the current configuration.  Returns
12875     * false if the activity had to be destroyed.  Returns true if the
12876     * configuration is the same, or the activity will remain running as-is
12877     * for whatever reason.  Ensures the HistoryRecord is updated with the
12878     * correct configuration and all other bookkeeping is handled.
12879     */
12880    private final boolean ensureActivityConfigurationLocked(HistoryRecord r,
12881            int globalChanges) {
12882        if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Log.v(TAG,
12883                "Ensuring correct configuration: " + r);
12884
12885        // Short circuit: if the two configurations are the exact same
12886        // object (the common case), then there is nothing to do.
12887        Configuration newConfig = mConfiguration;
12888        if (r.configuration == newConfig) {
12889            if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Log.v(TAG,
12890                    "Configuration unchanged in " + r);
12891            return true;
12892        }
12893
12894        // We don't worry about activities that are finishing.
12895        if (r.finishing) {
12896            if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Log.v(TAG,
12897                    "Configuration doesn't matter in finishing " + r);
12898            r.stopFreezingScreenLocked(false);
12899            return true;
12900        }
12901
12902        // Okay we now are going to make this activity have the new config.
12903        // But then we need to figure out how it needs to deal with that.
12904        Configuration oldConfig = r.configuration;
12905        r.configuration = newConfig;
12906
12907        // If the activity isn't currently running, just leave the new
12908        // configuration and it will pick that up next time it starts.
12909        if (r.app == null || r.app.thread == null) {
12910            if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Log.v(TAG,
12911                    "Configuration doesn't matter not running " + r);
12912            r.stopFreezingScreenLocked(false);
12913            return true;
12914        }
12915
12916        // If the activity isn't persistent, there is a chance we will
12917        // need to restart it.
12918        if (!r.persistent) {
12919
12920            // Figure out what has changed between the two configurations.
12921            int changes = oldConfig.diff(newConfig);
12922            if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
12923                Log.v(TAG, "Checking to restart " + r.info.name + ": changed=0x"
12924                        + Integer.toHexString(changes) + ", handles=0x"
12925                        + Integer.toHexString(r.info.configChanges)
12926                        + ", newConfig=" + newConfig);
12927            }
12928            if ((changes&(~r.info.configChanges)) != 0) {
12929                // Aha, the activity isn't handling the change, so DIE DIE DIE.
12930                r.configChangeFlags |= changes;
12931                r.startFreezingScreenLocked(r.app, globalChanges);
12932                if (r.app == null || r.app.thread == null) {
12933                    if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Log.v(TAG,
12934                            "Switch is destroying non-running " + r);
12935                    destroyActivityLocked(r, true);
12936                } else if (r.state == ActivityState.PAUSING) {
12937                    // A little annoying: we are waiting for this activity to
12938                    // finish pausing.  Let's not do anything now, but just
12939                    // flag that it needs to be restarted when done pausing.
12940                    if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Log.v(TAG,
12941                            "Switch is skipping already pausing " + r);
12942                    r.configDestroy = true;
12943                    return true;
12944                } else if (r.state == ActivityState.RESUMED) {
12945                    // Try to optimize this case: the configuration is changing
12946                    // and we need to restart the top, resumed activity.
12947                    // Instead of doing the normal handshaking, just say
12948                    // "restart!".
12949                    if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Log.v(TAG,
12950                            "Switch is restarting resumed " + r);
12951                    relaunchActivityLocked(r, r.configChangeFlags, true);
12952                    r.configChangeFlags = 0;
12953                } else {
12954                    if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Log.v(TAG,
12955                            "Switch is restarting non-resumed " + r);
12956                    relaunchActivityLocked(r, r.configChangeFlags, false);
12957                    r.configChangeFlags = 0;
12958                }
12959
12960                // All done...  tell the caller we weren't able to keep this
12961                // activity around.
12962                return false;
12963            }
12964        }
12965
12966        // Default case: the activity can handle this new configuration, so
12967        // hand it over.  Note that we don't need to give it the new
12968        // configuration, since we always send configuration changes to all
12969        // process when they happen so it can just use whatever configuration
12970        // it last got.
12971        if (r.app != null && r.app.thread != null) {
12972            try {
12973                if (DEBUG_CONFIGURATION) Log.v(TAG, "Sending new config to " + r);
12974                r.app.thread.scheduleActivityConfigurationChanged(r);
12975            } catch (RemoteException e) {
12976                // If process died, whatever.
12977            }
12978        }
12979        r.stopFreezingScreenLocked(false);
12980
12981        return true;
12982    }
12983
12984    /**
12985     * Save the locale.  You must be inside a synchronized (this) block.
12986     */
12987    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
12988        if(isDiff) {
12989            SystemProperties.set("user.language", l.getLanguage());
12990            SystemProperties.set("user.region", l.getCountry());
12991        }
12992
12993        if(isPersist) {
12994            SystemProperties.set("persist.sys.language", l.getLanguage());
12995            SystemProperties.set("persist.sys.country", l.getCountry());
12996            SystemProperties.set("persist.sys.localevar", l.getVariant());
12997        }
12998    }
12999
13000    // =========================================================
13001    // LIFETIME MANAGEMENT
13002    // =========================================================
13003
13004    private final int computeOomAdjLocked(
13005        ProcessRecord app, int hiddenAdj, ProcessRecord TOP_APP) {
13006        if (mAdjSeq == app.adjSeq) {
13007            // This adjustment has already been computed.
13008            return app.curAdj;
13009        }
13010
13011        if (app.thread == null) {
13012            app.adjSeq = mAdjSeq;
13013            return (app.curAdj=EMPTY_APP_ADJ);
13014        }
13015
13016        if (app.maxAdj <= FOREGROUND_APP_ADJ) {
13017            // The max adjustment doesn't allow this app to be anything
13018            // below foreground, so it is not worth doing work for it.
13019            app.adjType = "fixed";
13020            app.adjSeq = mAdjSeq;
13021            app.curRawAdj = app.maxAdj;
13022            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
13023            return (app.curAdj=app.maxAdj);
13024       }
13025
13026        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
13027        app.adjSource = null;
13028        app.adjTarget = null;
13029
13030        // Determine the importance of the process, starting with most
13031        // important to least, and assign an appropriate OOM adjustment.
13032        int adj;
13033        int N;
13034        if (app == TOP_APP) {
13035            // The last app on the list is the foreground app.
13036            adj = FOREGROUND_APP_ADJ;
13037            app.adjType = "top-activity";
13038        } else if (app.instrumentationClass != null) {
13039            // Don't want to kill running instrumentation.
13040            adj = FOREGROUND_APP_ADJ;
13041            app.adjType = "instrumentation";
13042        } else if (app.persistentActivities > 0) {
13043            // Special persistent activities...  shouldn't be used these days.
13044            adj = FOREGROUND_APP_ADJ;
13045            app.adjType = "persistent";
13046        } else if (app.curReceiver != null ||
13047                (mPendingBroadcast != null && mPendingBroadcast.curApp == app)) {
13048            // An app that is currently receiving a broadcast also
13049            // counts as being in the foreground.
13050            adj = FOREGROUND_APP_ADJ;
13051            app.adjType = "broadcast";
13052        } else if (app.executingServices.size() > 0) {
13053            // An app that is currently executing a service callback also
13054            // counts as being in the foreground.
13055            adj = FOREGROUND_APP_ADJ;
13056            app.adjType = "exec-service";
13057        } else if (app.foregroundServices) {
13058            // The user is aware of this app, so make it visible.
13059            adj = VISIBLE_APP_ADJ;
13060            app.adjType = "foreground-service";
13061        } else if (app.forcingToForeground != null) {
13062            // The user is aware of this app, so make it visible.
13063            adj = VISIBLE_APP_ADJ;
13064            app.adjType = "force-foreground";
13065            app.adjSource = app.forcingToForeground;
13066        } else if (app == mHomeProcess) {
13067            // This process is hosting what we currently consider to be the
13068            // home app, so we don't want to let it go into the background.
13069            adj = HOME_APP_ADJ;
13070            app.adjType = "home";
13071        } else if ((N=app.activities.size()) != 0) {
13072            // This app is in the background with paused activities.
13073            adj = hiddenAdj;
13074            app.adjType = "bg-activities";
13075            for (int j=0; j<N; j++) {
13076                if (((HistoryRecord)app.activities.get(j)).visible) {
13077                    // This app has a visible activity!
13078                    adj = VISIBLE_APP_ADJ;
13079                    app.adjType = "visible";
13080                    break;
13081                }
13082            }
13083        } else {
13084            // A very not-needed process.
13085            adj = EMPTY_APP_ADJ;
13086            app.adjType = "empty";
13087        }
13088
13089        // By default, we use the computed adjustment.  It may be changed if
13090        // there are applications dependent on our services or providers, but
13091        // this gives us a baseline and makes sure we don't get into an
13092        // infinite recursion.
13093        app.adjSeq = mAdjSeq;
13094        app.curRawAdj = adj;
13095        app.curAdj = adj <= app.maxAdj ? adj : app.maxAdj;
13096
13097        if (mBackupTarget != null && app == mBackupTarget.app) {
13098            // If possible we want to avoid killing apps while they're being backed up
13099            if (adj > BACKUP_APP_ADJ) {
13100                if (DEBUG_BACKUP) Log.v(TAG, "oom BACKUP_APP_ADJ for " + app);
13101                adj = BACKUP_APP_ADJ;
13102                app.adjType = "backup";
13103            }
13104        }
13105
13106        if (app.services.size() != 0 && adj > FOREGROUND_APP_ADJ) {
13107            final long now = SystemClock.uptimeMillis();
13108            // This process is more important if the top activity is
13109            // bound to the service.
13110            Iterator jt = app.services.iterator();
13111            while (jt.hasNext() && adj > FOREGROUND_APP_ADJ) {
13112                ServiceRecord s = (ServiceRecord)jt.next();
13113                if (s.startRequested) {
13114                    if (now < (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
13115                        // This service has seen some activity within
13116                        // recent memory, so we will keep its process ahead
13117                        // of the background processes.
13118                        if (adj > SECONDARY_SERVER_ADJ) {
13119                            adj = SECONDARY_SERVER_ADJ;
13120                            app.adjType = "started-services";
13121                        }
13122                    }
13123                }
13124                if (s.connections.size() > 0 && adj > FOREGROUND_APP_ADJ) {
13125                    Iterator<ConnectionRecord> kt
13126                            = s.connections.values().iterator();
13127                    while (kt.hasNext() && adj > FOREGROUND_APP_ADJ) {
13128                        // XXX should compute this based on the max of
13129                        // all connected clients.
13130                        ConnectionRecord cr = kt.next();
13131                        if (cr.binding.client == app) {
13132                            // Binding to ourself is not interesting.
13133                            continue;
13134                        }
13135                        if ((cr.flags&Context.BIND_AUTO_CREATE) != 0) {
13136                            ProcessRecord client = cr.binding.client;
13137                            int myHiddenAdj = hiddenAdj;
13138                            if (myHiddenAdj > client.hiddenAdj) {
13139                                if (client.hiddenAdj > VISIBLE_APP_ADJ) {
13140                                    myHiddenAdj = client.hiddenAdj;
13141                                } else {
13142                                    myHiddenAdj = VISIBLE_APP_ADJ;
13143                                }
13144                            }
13145                            int clientAdj = computeOomAdjLocked(
13146                                client, myHiddenAdj, TOP_APP);
13147                            if (adj > clientAdj) {
13148                                adj = clientAdj > VISIBLE_APP_ADJ
13149                                        ? clientAdj : VISIBLE_APP_ADJ;
13150                                app.adjType = "service";
13151                                app.adjTypeCode = ActivityManager.RunningAppProcessInfo
13152                                        .REASON_SERVICE_IN_USE;
13153                                app.adjSource = cr.binding.client;
13154                                app.adjTarget = s.serviceInfo.name;
13155                            }
13156                        }
13157                        HistoryRecord a = cr.activity;
13158                        //if (a != null) {
13159                        //    Log.i(TAG, "Connection to " + a ": state=" + a.state);
13160                        //}
13161                        if (a != null && adj > FOREGROUND_APP_ADJ &&
13162                                (a.state == ActivityState.RESUMED
13163                                 || a.state == ActivityState.PAUSING)) {
13164                            adj = FOREGROUND_APP_ADJ;
13165                            app.adjType = "service";
13166                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
13167                                    .REASON_SERVICE_IN_USE;
13168                            app.adjSource = a;
13169                            app.adjTarget = s.serviceInfo.name;
13170                        }
13171                    }
13172                }
13173            }
13174
13175            // Finally, f this process has active services running in it, we
13176            // would like to avoid killing it unless it would prevent the current
13177            // application from running.  By default we put the process in
13178            // with the rest of the background processes; as we scan through
13179            // its services we may bump it up from there.
13180            if (adj > hiddenAdj) {
13181                adj = hiddenAdj;
13182                app.adjType = "bg-services";
13183            }
13184        }
13185
13186        if (app.pubProviders.size() != 0 && adj > FOREGROUND_APP_ADJ) {
13187            Iterator jt = app.pubProviders.values().iterator();
13188            while (jt.hasNext() && adj > FOREGROUND_APP_ADJ) {
13189                ContentProviderRecord cpr = (ContentProviderRecord)jt.next();
13190                if (cpr.clients.size() != 0) {
13191                    Iterator<ProcessRecord> kt = cpr.clients.iterator();
13192                    while (kt.hasNext() && adj > FOREGROUND_APP_ADJ) {
13193                        ProcessRecord client = kt.next();
13194                        if (client == app) {
13195                            // Being our own client is not interesting.
13196                            continue;
13197                        }
13198                        int myHiddenAdj = hiddenAdj;
13199                        if (myHiddenAdj > client.hiddenAdj) {
13200                            if (client.hiddenAdj > FOREGROUND_APP_ADJ) {
13201                                myHiddenAdj = client.hiddenAdj;
13202                            } else {
13203                                myHiddenAdj = FOREGROUND_APP_ADJ;
13204                            }
13205                        }
13206                        int clientAdj = computeOomAdjLocked(
13207                            client, myHiddenAdj, TOP_APP);
13208                        if (adj > clientAdj) {
13209                            adj = clientAdj > FOREGROUND_APP_ADJ
13210                                    ? clientAdj : FOREGROUND_APP_ADJ;
13211                            app.adjType = "provider";
13212                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
13213                                    .REASON_PROVIDER_IN_USE;
13214                            app.adjSource = client;
13215                            app.adjTarget = cpr.info.name;
13216                        }
13217                    }
13218                }
13219                // If the provider has external (non-framework) process
13220                // dependencies, ensure that its adjustment is at least
13221                // FOREGROUND_APP_ADJ.
13222                if (cpr.externals != 0) {
13223                    if (adj > FOREGROUND_APP_ADJ) {
13224                        adj = FOREGROUND_APP_ADJ;
13225                        app.adjType = "provider";
13226                        app.adjTarget = cpr.info.name;
13227                    }
13228                }
13229            }
13230
13231            // Finally, if this process has published any content providers,
13232            // then its adjustment makes it at least as important as any of the
13233            // processes using those providers, and no less important than
13234            // CONTENT_PROVIDER_ADJ, which is just shy of EMPTY.
13235            if (adj > CONTENT_PROVIDER_ADJ) {
13236                adj = CONTENT_PROVIDER_ADJ;
13237                app.adjType = "pub-providers";
13238            }
13239        }
13240
13241        app.curRawAdj = adj;
13242
13243        //Log.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
13244        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
13245        if (adj > app.maxAdj) {
13246            adj = app.maxAdj;
13247        }
13248
13249        app.curAdj = adj;
13250        app.curSchedGroup = adj > VISIBLE_APP_ADJ
13251                ? Process.THREAD_GROUP_BG_NONINTERACTIVE
13252                : Process.THREAD_GROUP_DEFAULT;
13253
13254        return adj;
13255    }
13256
13257    /**
13258     * Ask a given process to GC right now.
13259     */
13260    final void performAppGcLocked(ProcessRecord app) {
13261        try {
13262            app.lastRequestedGc = SystemClock.uptimeMillis();
13263            if (app.thread != null) {
13264                if (app.reportLowMemory) {
13265                    app.reportLowMemory = false;
13266                    app.thread.scheduleLowMemory();
13267                } else {
13268                    app.thread.processInBackground();
13269                }
13270            }
13271        } catch (Exception e) {
13272            // whatever.
13273        }
13274    }
13275
13276    /**
13277     * Returns true if things are idle enough to perform GCs.
13278     */
13279    private final boolean canGcNow() {
13280        return mParallelBroadcasts.size() == 0
13281                && mOrderedBroadcasts.size() == 0
13282                && (mSleeping || (mResumedActivity != null &&
13283                        mResumedActivity.idle));
13284    }
13285
13286    /**
13287     * Perform GCs on all processes that are waiting for it, but only
13288     * if things are idle.
13289     */
13290    final void performAppGcsLocked() {
13291        final int N = mProcessesToGc.size();
13292        if (N <= 0) {
13293            return;
13294        }
13295        if (canGcNow()) {
13296            while (mProcessesToGc.size() > 0) {
13297                ProcessRecord proc = mProcessesToGc.remove(0);
13298                if (proc.curRawAdj > VISIBLE_APP_ADJ || proc.reportLowMemory) {
13299                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
13300                            <= SystemClock.uptimeMillis()) {
13301                        // To avoid spamming the system, we will GC processes one
13302                        // at a time, waiting a few seconds between each.
13303                        performAppGcLocked(proc);
13304                        scheduleAppGcsLocked();
13305                        return;
13306                    } else {
13307                        // It hasn't been long enough since we last GCed this
13308                        // process...  put it in the list to wait for its time.
13309                        addProcessToGcListLocked(proc);
13310                        break;
13311                    }
13312                }
13313            }
13314
13315            scheduleAppGcsLocked();
13316        }
13317    }
13318
13319    /**
13320     * If all looks good, perform GCs on all processes waiting for them.
13321     */
13322    final void performAppGcsIfAppropriateLocked() {
13323        if (canGcNow()) {
13324            performAppGcsLocked();
13325            return;
13326        }
13327        // Still not idle, wait some more.
13328        scheduleAppGcsLocked();
13329    }
13330
13331    /**
13332     * Schedule the execution of all pending app GCs.
13333     */
13334    final void scheduleAppGcsLocked() {
13335        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
13336
13337        if (mProcessesToGc.size() > 0) {
13338            // Schedule a GC for the time to the next process.
13339            ProcessRecord proc = mProcessesToGc.get(0);
13340            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
13341
13342            long when = mProcessesToGc.get(0).lastRequestedGc + GC_MIN_INTERVAL;
13343            long now = SystemClock.uptimeMillis();
13344            if (when < (now+GC_TIMEOUT)) {
13345                when = now + GC_TIMEOUT;
13346            }
13347            mHandler.sendMessageAtTime(msg, when);
13348        }
13349    }
13350
13351    /**
13352     * Add a process to the array of processes waiting to be GCed.  Keeps the
13353     * list in sorted order by the last GC time.  The process can't already be
13354     * on the list.
13355     */
13356    final void addProcessToGcListLocked(ProcessRecord proc) {
13357        boolean added = false;
13358        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
13359            if (mProcessesToGc.get(i).lastRequestedGc <
13360                    proc.lastRequestedGc) {
13361                added = true;
13362                mProcessesToGc.add(i+1, proc);
13363                break;
13364            }
13365        }
13366        if (!added) {
13367            mProcessesToGc.add(0, proc);
13368        }
13369    }
13370
13371    /**
13372     * Set up to ask a process to GC itself.  This will either do it
13373     * immediately, or put it on the list of processes to gc the next
13374     * time things are idle.
13375     */
13376    final void scheduleAppGcLocked(ProcessRecord app) {
13377        long now = SystemClock.uptimeMillis();
13378        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
13379            return;
13380        }
13381        if (!mProcessesToGc.contains(app)) {
13382            addProcessToGcListLocked(app);
13383            scheduleAppGcsLocked();
13384        }
13385    }
13386
13387    private final boolean updateOomAdjLocked(
13388        ProcessRecord app, int hiddenAdj, ProcessRecord TOP_APP) {
13389        app.hiddenAdj = hiddenAdj;
13390
13391        if (app.thread == null) {
13392            return true;
13393        }
13394
13395        int adj = computeOomAdjLocked(app, hiddenAdj, TOP_APP);
13396
13397        if (app.pid != 0 && app.pid != MY_PID) {
13398            if (app.curRawAdj != app.setRawAdj) {
13399                if (app.curRawAdj > FOREGROUND_APP_ADJ
13400                        && app.setRawAdj <= FOREGROUND_APP_ADJ) {
13401                    // If this app is transitioning from foreground to
13402                    // non-foreground, have it do a gc.
13403                    scheduleAppGcLocked(app);
13404                } else if (app.curRawAdj >= HIDDEN_APP_MIN_ADJ
13405                        && app.setRawAdj < HIDDEN_APP_MIN_ADJ) {
13406                    // Likewise do a gc when an app is moving in to the
13407                    // background (such as a service stopping).
13408                    scheduleAppGcLocked(app);
13409                }
13410                app.setRawAdj = app.curRawAdj;
13411            }
13412            if (adj != app.setAdj) {
13413                if (Process.setOomAdj(app.pid, adj)) {
13414                    if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Log.v(
13415                        TAG, "Set app " + app.processName +
13416                        " oom adj to " + adj);
13417                    app.setAdj = adj;
13418                } else {
13419                    return false;
13420                }
13421            }
13422            if (app.setSchedGroup != app.curSchedGroup) {
13423                app.setSchedGroup = app.curSchedGroup;
13424                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Log.v(TAG,
13425                        "Setting process group of " + app.processName
13426                        + " to " + app.curSchedGroup);
13427                if (true) {
13428                    long oldId = Binder.clearCallingIdentity();
13429                    try {
13430                        Process.setProcessGroup(app.pid, app.curSchedGroup);
13431                    } catch (Exception e) {
13432                        Log.w(TAG, "Failed setting process group of " + app.pid
13433                                + " to " + app.curSchedGroup);
13434                        e.printStackTrace();
13435                    } finally {
13436                        Binder.restoreCallingIdentity(oldId);
13437                    }
13438                }
13439                if (false) {
13440                    if (app.thread != null) {
13441                        try {
13442                            app.thread.setSchedulingGroup(app.curSchedGroup);
13443                        } catch (RemoteException e) {
13444                        }
13445                    }
13446                }
13447            }
13448        }
13449
13450        return true;
13451    }
13452
13453    private final HistoryRecord resumedAppLocked() {
13454        HistoryRecord resumedActivity = mResumedActivity;
13455        if (resumedActivity == null || resumedActivity.app == null) {
13456            resumedActivity = mPausingActivity;
13457            if (resumedActivity == null || resumedActivity.app == null) {
13458                resumedActivity = topRunningActivityLocked(null);
13459            }
13460        }
13461        return resumedActivity;
13462    }
13463
13464    private final boolean updateOomAdjLocked(ProcessRecord app) {
13465        final HistoryRecord TOP_ACT = resumedAppLocked();
13466        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13467        int curAdj = app.curAdj;
13468        final boolean wasHidden = app.curAdj >= HIDDEN_APP_MIN_ADJ
13469            && app.curAdj <= HIDDEN_APP_MAX_ADJ;
13470
13471        mAdjSeq++;
13472
13473        final boolean res = updateOomAdjLocked(app, app.hiddenAdj, TOP_APP);
13474        if (res) {
13475            final boolean nowHidden = app.curAdj >= HIDDEN_APP_MIN_ADJ
13476                && app.curAdj <= HIDDEN_APP_MAX_ADJ;
13477            if (nowHidden != wasHidden) {
13478                // Changed to/from hidden state, so apps after it in the LRU
13479                // list may also be changed.
13480                updateOomAdjLocked();
13481            }
13482        }
13483        return res;
13484    }
13485
13486    private final boolean updateOomAdjLocked() {
13487        boolean didOomAdj = true;
13488        final HistoryRecord TOP_ACT = resumedAppLocked();
13489        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13490
13491        if (false) {
13492            RuntimeException e = new RuntimeException();
13493            e.fillInStackTrace();
13494            Log.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
13495        }
13496
13497        mAdjSeq++;
13498
13499        // First try updating the OOM adjustment for each of the
13500        // application processes based on their current state.
13501        int i = mLRUProcesses.size();
13502        int curHiddenAdj = HIDDEN_APP_MIN_ADJ;
13503        while (i > 0) {
13504            i--;
13505            ProcessRecord app = mLRUProcesses.get(i);
13506            if (updateOomAdjLocked(app, curHiddenAdj, TOP_APP)) {
13507                if (curHiddenAdj < HIDDEN_APP_MAX_ADJ
13508                    && app.curAdj == curHiddenAdj) {
13509                    curHiddenAdj++;
13510                }
13511            } else {
13512                didOomAdj = false;
13513            }
13514        }
13515
13516        // todo: for now pretend like OOM ADJ didn't work, because things
13517        // aren't behaving as expected on Linux -- it's not killing processes.
13518        return ENFORCE_PROCESS_LIMIT || mProcessLimit > 0 ? false : didOomAdj;
13519    }
13520
13521    private final void trimApplications() {
13522        synchronized (this) {
13523            int i;
13524
13525            // First remove any unused application processes whose package
13526            // has been removed.
13527            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
13528                final ProcessRecord app = mRemovedProcesses.get(i);
13529                if (app.activities.size() == 0
13530                        && app.curReceiver == null && app.services.size() == 0) {
13531                    Log.i(
13532                        TAG, "Exiting empty application process "
13533                        + app.processName + " ("
13534                        + (app.thread != null ? app.thread.asBinder() : null)
13535                        + ")\n");
13536                    if (app.pid > 0 && app.pid != MY_PID) {
13537                        Process.killProcess(app.pid);
13538                    } else {
13539                        try {
13540                            app.thread.scheduleExit();
13541                        } catch (Exception e) {
13542                            // Ignore exceptions.
13543                        }
13544                    }
13545                    cleanUpApplicationRecordLocked(app, false, -1);
13546                    mRemovedProcesses.remove(i);
13547
13548                    if (app.persistent) {
13549                        if (app.persistent) {
13550                            addAppLocked(app.info);
13551                        }
13552                    }
13553                }
13554            }
13555
13556            // Now try updating the OOM adjustment for each of the
13557            // application processes based on their current state.
13558            // If the setOomAdj() API is not supported, then go with our
13559            // back-up plan...
13560            if (!updateOomAdjLocked()) {
13561
13562                // Count how many processes are running services.
13563                int numServiceProcs = 0;
13564                for (i=mLRUProcesses.size()-1; i>=0; i--) {
13565                    final ProcessRecord app = mLRUProcesses.get(i);
13566
13567                    if (app.persistent || app.services.size() != 0
13568                            || app.curReceiver != null
13569                            || app.persistentActivities > 0) {
13570                        // Don't count processes holding services against our
13571                        // maximum process count.
13572                        if (localLOGV) Log.v(
13573                            TAG, "Not trimming app " + app + " with services: "
13574                            + app.services);
13575                        numServiceProcs++;
13576                    }
13577                }
13578
13579                int curMaxProcs = mProcessLimit;
13580                if (curMaxProcs <= 0) curMaxProcs = MAX_PROCESSES;
13581                if (mAlwaysFinishActivities) {
13582                    curMaxProcs = 1;
13583                }
13584                curMaxProcs += numServiceProcs;
13585
13586                // Quit as many processes as we can to get down to the desired
13587                // process count.  First remove any processes that no longer
13588                // have activites running in them.
13589                for (   i=0;
13590                        i<mLRUProcesses.size()
13591                            && mLRUProcesses.size() > curMaxProcs;
13592                        i++) {
13593                    final ProcessRecord app = mLRUProcesses.get(i);
13594                    // Quit an application only if it is not currently
13595                    // running any activities.
13596                    if (!app.persistent && app.activities.size() == 0
13597                            && app.curReceiver == null && app.services.size() == 0) {
13598                        Log.i(
13599                            TAG, "Exiting empty application process "
13600                            + app.processName + " ("
13601                            + (app.thread != null ? app.thread.asBinder() : null)
13602                            + ")\n");
13603                        if (app.pid > 0 && app.pid != MY_PID) {
13604                            Process.killProcess(app.pid);
13605                        } else {
13606                            try {
13607                                app.thread.scheduleExit();
13608                            } catch (Exception e) {
13609                                // Ignore exceptions.
13610                            }
13611                        }
13612                        // todo: For now we assume the application is not buggy
13613                        // or evil, and will quit as a result of our request.
13614                        // Eventually we need to drive this off of the death
13615                        // notification, and kill the process if it takes too long.
13616                        cleanUpApplicationRecordLocked(app, false, i);
13617                        i--;
13618                    }
13619                }
13620
13621                // If we still have too many processes, now from the least
13622                // recently used process we start finishing activities.
13623                if (Config.LOGV) Log.v(
13624                    TAG, "*** NOW HAVE " + mLRUProcesses.size() +
13625                    " of " + curMaxProcs + " processes");
13626                for (   i=0;
13627                        i<mLRUProcesses.size()
13628                            && mLRUProcesses.size() > curMaxProcs;
13629                        i++) {
13630                    final ProcessRecord app = mLRUProcesses.get(i);
13631                    // Quit the application only if we have a state saved for
13632                    // all of its activities.
13633                    boolean canQuit = !app.persistent && app.curReceiver == null
13634                        && app.services.size() == 0
13635                        && app.persistentActivities == 0;
13636                    int NUMA = app.activities.size();
13637                    int j;
13638                    if (Config.LOGV) Log.v(
13639                        TAG, "Looking to quit " + app.processName);
13640                    for (j=0; j<NUMA && canQuit; j++) {
13641                        HistoryRecord r = (HistoryRecord)app.activities.get(j);
13642                        if (Config.LOGV) Log.v(
13643                            TAG, "  " + r.intent.getComponent().flattenToShortString()
13644                            + ": frozen=" + r.haveState + ", visible=" + r.visible);
13645                        canQuit = (r.haveState || !r.stateNotNeeded)
13646                                && !r.visible && r.stopped;
13647                    }
13648                    if (canQuit) {
13649                        // Finish all of the activities, and then the app itself.
13650                        for (j=0; j<NUMA; j++) {
13651                            HistoryRecord r = (HistoryRecord)app.activities.get(j);
13652                            if (!r.finishing) {
13653                                destroyActivityLocked(r, false);
13654                            }
13655                            r.resultTo = null;
13656                        }
13657                        Log.i(TAG, "Exiting application process "
13658                              + app.processName + " ("
13659                              + (app.thread != null ? app.thread.asBinder() : null)
13660                              + ")\n");
13661                        if (app.pid > 0 && app.pid != MY_PID) {
13662                            Process.killProcess(app.pid);
13663                        } else {
13664                            try {
13665                                app.thread.scheduleExit();
13666                            } catch (Exception e) {
13667                                // Ignore exceptions.
13668                            }
13669                        }
13670                        // todo: For now we assume the application is not buggy
13671                        // or evil, and will quit as a result of our request.
13672                        // Eventually we need to drive this off of the death
13673                        // notification, and kill the process if it takes too long.
13674                        cleanUpApplicationRecordLocked(app, false, i);
13675                        i--;
13676                        //dump();
13677                    }
13678                }
13679
13680            }
13681
13682            int curMaxActivities = MAX_ACTIVITIES;
13683            if (mAlwaysFinishActivities) {
13684                curMaxActivities = 1;
13685            }
13686
13687            // Finally, if there are too many activities now running, try to
13688            // finish as many as we can to get back down to the limit.
13689            for (   i=0;
13690                    i<mLRUActivities.size()
13691                        && mLRUActivities.size() > curMaxActivities;
13692                    i++) {
13693                final HistoryRecord r
13694                    = (HistoryRecord)mLRUActivities.get(i);
13695
13696                // We can finish this one if we have its icicle saved and
13697                // it is not persistent.
13698                if ((r.haveState || !r.stateNotNeeded) && !r.visible
13699                        && r.stopped && !r.persistent && !r.finishing) {
13700                    final int origSize = mLRUActivities.size();
13701                    destroyActivityLocked(r, true);
13702
13703                    // This will remove it from the LRU list, so keep
13704                    // our index at the same value.  Note that this check to
13705                    // see if the size changes is just paranoia -- if
13706                    // something unexpected happens, we don't want to end up
13707                    // in an infinite loop.
13708                    if (origSize > mLRUActivities.size()) {
13709                        i--;
13710                    }
13711                }
13712            }
13713        }
13714    }
13715
13716    /** This method sends the specified signal to each of the persistent apps */
13717    public void signalPersistentProcesses(int sig) throws RemoteException {
13718        if (sig != Process.SIGNAL_USR1) {
13719            throw new SecurityException("Only SIGNAL_USR1 is allowed");
13720        }
13721
13722        synchronized (this) {
13723            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
13724                    != PackageManager.PERMISSION_GRANTED) {
13725                throw new SecurityException("Requires permission "
13726                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
13727            }
13728
13729            for (int i = mLRUProcesses.size() - 1 ; i >= 0 ; i--) {
13730                ProcessRecord r = mLRUProcesses.get(i);
13731                if (r.thread != null && r.persistent) {
13732                    Process.sendSignal(r.pid, sig);
13733                }
13734            }
13735        }
13736    }
13737
13738    public boolean profileControl(String process, boolean start,
13739            String path, ParcelFileDescriptor fd) throws RemoteException {
13740
13741        try {
13742            synchronized (this) {
13743                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13744                // its own permission.
13745                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13746                        != PackageManager.PERMISSION_GRANTED) {
13747                    throw new SecurityException("Requires permission "
13748                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13749                }
13750
13751                if (start && fd == null) {
13752                    throw new IllegalArgumentException("null fd");
13753                }
13754
13755                ProcessRecord proc = null;
13756                try {
13757                    int pid = Integer.parseInt(process);
13758                    synchronized (mPidsSelfLocked) {
13759                        proc = mPidsSelfLocked.get(pid);
13760                    }
13761                } catch (NumberFormatException e) {
13762                }
13763
13764                if (proc == null) {
13765                    HashMap<String, SparseArray<ProcessRecord>> all
13766                            = mProcessNames.getMap();
13767                    SparseArray<ProcessRecord> procs = all.get(process);
13768                    if (procs != null && procs.size() > 0) {
13769                        proc = procs.valueAt(0);
13770                    }
13771                }
13772
13773                if (proc == null || proc.thread == null) {
13774                    throw new IllegalArgumentException("Unknown process: " + process);
13775                }
13776
13777                boolean isSecure = "1".equals(SystemProperties.get(SYSTEM_SECURE, "0"));
13778                if (isSecure) {
13779                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
13780                        throw new SecurityException("Process not debuggable: " + proc);
13781                    }
13782                }
13783
13784                proc.thread.profilerControl(start, path, fd);
13785                fd = null;
13786                return true;
13787            }
13788        } catch (RemoteException e) {
13789            throw new IllegalStateException("Process disappeared");
13790        } finally {
13791            if (fd != null) {
13792                try {
13793                    fd.close();
13794                } catch (IOException e) {
13795                }
13796            }
13797        }
13798    }
13799
13800    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
13801    public void monitor() {
13802        synchronized (this) { }
13803    }
13804}
13805